mirror of
https://github.com/Relintai/pandemonium_engine_docs.git
synced 2025-01-21 15:07:22 +01:00
Markdown image syntax.
This commit is contained in:
parent
8a5415960b
commit
5da30da277
@ -49,7 +49,7 @@ Sphinx uses specific reST comments to do specific operations, like defining the
|
||||
|
||||
To add images, please put them in an `img/` folder next to the .rst file with a meaningful name and include them in your page with:
|
||||
```rst
|
||||
.. image:: img/image_name.png
|
||||
![](img/image_name.png)
|
||||
```
|
||||
|
||||
Similarly, you can include attachments (like assets as support material for a tutorial) by placing them into a `files/` folder next to the .rst file, and using this inline markup:
|
||||
|
@ -116,10 +116,10 @@ on GitHub.
|
||||
| Godot 1.0 | December 2014 | |eol| No longer supported. |
|
||||
+-------------+----------------------+--------------------------------------------------------------------------+
|
||||
|
||||
.. |supported| image:: img/supported.png
|
||||
.. |partial| image:: img/partial.png
|
||||
.. |eol| image:: img/eol.png
|
||||
.. |unstable| image:: img/unstable.png
|
||||
.. |supported| image:: img/supported.png)
|
||||
.. |partial| image:: img/partial.png)
|
||||
.. |eol| image:: img/eol.png)
|
||||
.. |unstable| image:: img/unstable.png)
|
||||
|
||||
**Legend:**
|
||||
|supported| Full support –
|
||||
|
@ -38,7 +38,7 @@ abstract data structures, creating nice user interfaces, or simply love
|
||||
programming. Whatever the case may be, they come up with cool ideas, which may
|
||||
or may not be solving any real problems.
|
||||
|
||||
.. image:: img/best_practices1.png
|
||||
![](img/best_practices1.png)
|
||||
|
||||
These are usually called *Solutions in search of a problem*. In an ideal world,
|
||||
they would not be harmful but, in reality, code takes time to write, takes space
|
||||
@ -52,7 +52,7 @@ software development.
|
||||
This is a variation of the previous practice. Adding anything unnecessary is not
|
||||
a good idea, but what constitutes what is necessary and what isn't?
|
||||
|
||||
.. image:: img/best_practices2.png
|
||||
![](img/best_practices2.png)
|
||||
|
||||
The answer to this question is that the problem needs to *exist* before it can
|
||||
be actually solved. It must not be speculation or a belief. The user must be
|
||||
@ -80,7 +80,7 @@ problem that exists under the sun*. As a game engine, Godot will solve problems
|
||||
for you, so it helps you to make games better and faster, but it won't make the
|
||||
*entire game* for you. A line must be drawn somewhere.
|
||||
|
||||
.. image:: img/best_practices3.png
|
||||
![](img/best_practices3.png)
|
||||
|
||||
Whether a problem is worth solving is determined by the difficulty the user has
|
||||
to work around it. This difficulty can be expressed as:
|
||||
@ -112,7 +112,7 @@ Because of this, user proposed solutions don't always contemplate other use
|
||||
cases that developers are often aware of, so they are often biased towards their
|
||||
own requirements.
|
||||
|
||||
.. image:: img/best_practices4.png
|
||||
![](img/best_practices4.png)
|
||||
|
||||
For developers, the perspective is different. They may find the user's problem
|
||||
too unique to justify a solution (instead of a user workaround), or maybe they
|
||||
@ -145,7 +145,7 @@ The situation will often take a turn for the worse when, in order to make this
|
||||
solution appear even more fantastic and flexible, the pure speculation-based
|
||||
problems (as described in #2) also make their appearance on stage.
|
||||
|
||||
.. image:: img/best_practices5.png
|
||||
![](img/best_practices5.png)
|
||||
|
||||
The main problem is that, in reality, it rarely works this way. Most of the
|
||||
time, writing an individual solution to each problem results in code that
|
||||
@ -180,7 +180,7 @@ The question is then, how to design software that gives users what *we know they
|
||||
need*, but that is flexible enough to allow them to do *what we don't know they
|
||||
might need* in the future?
|
||||
|
||||
.. image:: img/best_practices6.png
|
||||
![](img/best_practices6.png)
|
||||
|
||||
The answer to this question is that, to ensure users still can do what they want
|
||||
to do, we need to give them access to a *low level API* that they can use to
|
||||
@ -208,7 +208,7 @@ importance given how much code relies on it, and because it's key for new
|
||||
contributors as a starting point to learning the codebase.
|
||||
|
||||
|
||||
.. image:: img/best_practices7.png
|
||||
![](img/best_practices7.png)
|
||||
|
||||
|
||||
The common reasoning for wanting to do this is that it's usually less code to
|
||||
@ -228,7 +228,7 @@ use a third party library to solve the problem.
|
||||
As Godot requires to be shipped in a large amount of platforms, we can't
|
||||
link libraries dynamically. Instead, we bundle them in our source tree.
|
||||
|
||||
.. image:: img/best_practices8.png
|
||||
![](img/best_practices8.png)
|
||||
|
||||
As a result, we are very picky with what goes in, and we tend to prefer smaller
|
||||
libraries (in fact, single header ones are our favorite). Only in cases where
|
||||
|
@ -165,7 +165,7 @@ a meaningful name and include them in your page with:
|
||||
|
||||
.. code:: rst
|
||||
|
||||
.. image:: img/image_name.png
|
||||
![](img/image_name.png)
|
||||
|
||||
Similarly, you can include attachments, like assets as support material for a
|
||||
tutorial, by placing them into a `files/` folder next to the `.rst` file, and
|
||||
|
@ -461,7 +461,7 @@ interface. They're used in the sources, in the documentation, and you
|
||||
should always use them instead of synonyms, so the users know what
|
||||
you're talking about.
|
||||
|
||||
.. figure:: img/editor-vocabulary-overview.png
|
||||
.. figure:: img/editor-vocabulary-overview.png)
|
||||
:alt: Overview of the interface and common vocabulary
|
||||
|
||||
Overview of the interface and common vocabulary
|
||||
|
@ -120,7 +120,7 @@ Translating existing pages
|
||||
|
||||
You can help to translate the official Godot documentation on our `Hosted Weblate <https://hosted.weblate.org/engage/godot-engine/>`_.
|
||||
|
||||
.. image:: https://hosted.weblate.org/widgets/godot-engine/-/godot-docs/287x66-white.png
|
||||
![](https://hosted.weblate.org/widgets/godot-engine/-/godot-docs/287x66-white.png)
|
||||
:alt: Translation state
|
||||
:align: center
|
||||
:target: https://hosted.weblate.org/engage/godot-engine/?utm_source=widget
|
||||
|
@ -52,7 +52,7 @@ Once signed in, browse to the Godot resource which you want to contribute to (in
|
||||
this page we will use the `editor translation <https://hosted.weblate.org/projects/godot-engine/godot/>`__
|
||||
as an example) to find the list of all languages:
|
||||
|
||||
.. image:: img/l10n_01_language_list.png
|
||||
![](img/l10n_01_language_list.png)
|
||||
|
||||
.. seealso::
|
||||
|
||||
@ -70,7 +70,7 @@ If your language is not listed, scroll to the bottom of the list of languages
|
||||
and click the "Start new translation" button, and select the language you want
|
||||
to translate to:
|
||||
|
||||
.. image:: img/l10n_02_new_translation.png
|
||||
![](img/l10n_02_new_translation.png)
|
||||
|
||||
.. important::
|
||||
|
||||
@ -102,12 +102,12 @@ can be clicked and used to browse through the corresponding list. You can also
|
||||
click the "Translate" button to get started on the list of strings needing
|
||||
action.
|
||||
|
||||
.. image:: img/l10n_03_translation_overview.png
|
||||
![](img/l10n_03_translation_overview.png)
|
||||
|
||||
After selecting a list of clicking "Translate", you will see the main
|
||||
translation interface where all the work happens:
|
||||
|
||||
.. image:: img/l10n_04_translation_interface.png
|
||||
![](img/l10n_04_translation_interface.png)
|
||||
|
||||
On that page, you have:
|
||||
|
||||
@ -186,9 +186,9 @@ A handy tool to locate specific pages/classes is to use Weblate's advanced
|
||||
search feature, and especially the "Location strings" query (which can also be
|
||||
used with the `location:` token, e.g. `location:nodes_and_scenes.rst`):
|
||||
|
||||
.. image:: img/l10n_05_search_location.png
|
||||
![](img/l10n_05_search_location.png)
|
||||
|
||||
.. image:: img/l10n_06_browse_by_location.png
|
||||
![](img/l10n_06_browse_by_location.png)
|
||||
|
||||
.. note::
|
||||
|
||||
@ -342,7 +342,7 @@ preferred PO editing application, such as `Poedit <https://poedit.net/>`__ or
|
||||
To download the PO file locally, browse to the translation overview for your
|
||||
language, and select the first item in the "Files" menu:
|
||||
|
||||
.. image:: img/l10n_07_download_po_file.png
|
||||
![](img/l10n_07_download_po_file.png)
|
||||
|
||||
Once you are done with a series of edits, use the "Upload translation" item in
|
||||
that same menu and select your file. Choose "Add as translation" for the file
|
||||
@ -389,14 +389,14 @@ documentation. To do so, browse the relevant page in the docs, e.g.
|
||||
`doc_intro_to_the_editor_interface`. Click the "Edit on GitHub" link in the
|
||||
top right corner:
|
||||
|
||||
.. image:: img/l10n_08_edit_on_github.png
|
||||
![](img/l10n_08_edit_on_github.png)
|
||||
|
||||
On GitHub, click on the image you want to translate. If relevant, click on
|
||||
"Download" to download it locally and edit it with an image edition tool.
|
||||
Note the full path to the image as it will be needed further down (here
|
||||
`getting_started/step_by_step/img/project_manager_first_open.png`).
|
||||
`getting_started/step_by_step/img/project_manager_first_open.png)`).
|
||||
|
||||
.. image:: img/l10n_09_path_to_image.png
|
||||
![](img/l10n_09_path_to_image.png)
|
||||
|
||||
Create your localized version of the image, either by editing the English one,
|
||||
or by taking a screenshot of the editor with your language, if it's an editor
|
||||
@ -404,13 +404,13 @@ screenshot. Some images may also have source files available in SVG format, so
|
||||
you can browse the `img/` folder which contains them to check for that.
|
||||
|
||||
Name your localized image like the original one, but with the language code
|
||||
added before the extension, e.g. `project_manager_first_open.png` would become
|
||||
`project_manager_first_open.fr.png` for the French localization.
|
||||
added before the extension, e.g. `project_manager_first_open.png)` would become
|
||||
`project_manager_first_open.fr.png)` for the French localization.
|
||||
|
||||
Finally, on godot-docs-l10n_, recreate the same folder structure as for the
|
||||
original image in the `images` subfolder
|
||||
(`GitHub <https://github.com/godotengine/godot-docs-l10n/tree/master/images>`_),
|
||||
and place your translated image there. In our example, the end result should be
|
||||
`images/getting_started/step_by_step/img/project_manager_first_open.fr.png`.
|
||||
`images/getting_started/step_by_step/img/project_manager_first_open.fr.png)`.
|
||||
|
||||
Repeat this for other images and `make a Pull Request <doc_pr_workflow>`.
|
||||
|
@ -76,12 +76,12 @@ repository on GitHub. To do so, you will need to have a GitHub account and to
|
||||
be logged in. In the top right corner of the repository's GitHub page, you
|
||||
should see the "Fork" button as shown below:
|
||||
|
||||
.. image:: img/github_fork_button.png
|
||||
![](img/github_fork_button.png)
|
||||
|
||||
Click it, and after a while you should be redirected to your own fork of the
|
||||
Godot repo, with your GitHub username as namespace:
|
||||
|
||||
.. image:: img/github_fork_url.png
|
||||
![](img/github_fork_url.png)
|
||||
|
||||
You can then *clone* your fork, i.e. create a local copy of the online
|
||||
repository (in Git speak, the *origin remote*). If you haven't already,
|
||||
@ -359,7 +359,7 @@ When you load your fork's branch on GitHub, you should see a line saying
|
||||
commits behind, if your `master` branch was out of sync with the upstream
|
||||
`master` branch).
|
||||
|
||||
.. image:: img/github_fork_make_pr.png
|
||||
![](img/github_fork_make_pr.png)
|
||||
|
||||
On that line, there is a "Pull request" link. Clicking it will open a form
|
||||
that will let you issue a pull request on the `godotengine/godot` upstream
|
||||
|
@ -31,18 +31,18 @@ If you have a GitHub account
|
||||
|
||||
- Open the pull request page. Click the **Checks** tab near the top of the page:
|
||||
|
||||
.. image:: img/testing_pull_requests_access_checks.png
|
||||
![](img/testing_pull_requests_access_checks.png)
|
||||
|
||||
- In the list of platforms that appears on the left, select your platform by clicking
|
||||
it then choose the type of build you need (editor or export template).
|
||||
If in doubt, select an editor build:
|
||||
|
||||
.. image:: img/testing_pull_requests_checks_platforms.png
|
||||
![](img/testing_pull_requests_checks_platforms.png)
|
||||
|
||||
- Click the **Artifacts** dropdown on the right of the page then click the artifact's
|
||||
name to download it:
|
||||
|
||||
.. image:: img/testing_pull_requests_checks_artifacts.png
|
||||
![](img/testing_pull_requests_checks_artifacts.png)
|
||||
|
||||
- Extract the ZIP archive then run the executable.
|
||||
Note that Windows and macOS binaries are not code signed.
|
||||
@ -59,7 +59,7 @@ to generate a universal download link.
|
||||
|
||||
- Open the pull request page. Click the *fork*'s branch name near the top of the page:
|
||||
|
||||
.. image:: img/testing_pull_requests_access_fork.png
|
||||
![](img/testing_pull_requests_access_fork.png)
|
||||
|
||||
- Now that you are on the fork's branch page, click the `.github` folder at the top of the file list.
|
||||
Then, click on the `workflows` folder (whicb is inside the `.github` folder).
|
||||
@ -72,7 +72,7 @@ to generate a universal download link.
|
||||
If the the format of the URL you pasted is correct, you should be presented
|
||||
with a page like this:
|
||||
|
||||
.. image:: img/testing_pull_requests_nightly_link.png
|
||||
![](img/testing_pull_requests_nightly_link.png)
|
||||
|
||||
- Click the URL of the artifact you wish to download.
|
||||
|
||||
@ -93,12 +93,12 @@ by Godot's GitHub Actions setup.
|
||||
|
||||
- Open the pull request page. Click the *fork*'s branch name near the top of the page:
|
||||
|
||||
.. image:: img/testing_pull_requests_access_fork.png
|
||||
![](img/testing_pull_requests_access_fork.png)
|
||||
|
||||
- Now that you are on the fork's branch page, click the green **Code** button on the right of the page
|
||||
then choose **Download ZIP** in the dropdown:
|
||||
|
||||
.. image:: img/testing_pull_requests_fork_zip.png
|
||||
![](img/testing_pull_requests_fork_zip.png)
|
||||
|
||||
- Extract the ZIP archive and follow the `compiling <toc-devel-compiling>` instructions
|
||||
for your operating system.
|
||||
|
@ -193,7 +193,7 @@ However, if you are writing your custom modules or custom C++ code, you
|
||||
might instead want to configure your APKs as custom export templates
|
||||
here:
|
||||
|
||||
.. image:: img/andtemplates.png
|
||||
![](img/andtemplates.png)
|
||||
|
||||
You don't even need to copy them, you can just reference the resulting
|
||||
file in the `bin\` directory of your Godot source folder, so that the
|
||||
|
@ -290,7 +290,7 @@ However, if you are using custom modules or custom engine code, you
|
||||
may instead want to configure your binaries as custom export templates
|
||||
here:
|
||||
|
||||
.. image:: img/wintemplates.png
|
||||
![](img/wintemplates.png)
|
||||
|
||||
You don't need to copy them in this case, just reference the resulting
|
||||
files in the `bin\` directory of your Godot source folder, so the next
|
||||
|
@ -210,7 +210,7 @@ However, if you are writing your custom modules or custom C++ code, you
|
||||
might instead want to configure your binaries as custom export templates
|
||||
here:
|
||||
|
||||
.. image:: img/lintemplates.png
|
||||
![](img/lintemplates.png)
|
||||
|
||||
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
|
||||
|
@ -65,7 +65,7 @@ bat Windows (PowerShell)
|
||||
|
||||
4. Set the encryption key in the **Script** tab of the export preset:
|
||||
|
||||
.. image:: img/script_encryption_key.png
|
||||
![](img/script_encryption_key.png)
|
||||
|
||||
5. Export the project. The game should run with encrypted scripts now.
|
||||
|
||||
|
@ -14,7 +14,7 @@ Importing the project
|
||||
- From the Android Studio's welcome window select **Open an existing
|
||||
Android Studio project**.
|
||||
|
||||
.. figure:: img/android_studio_setup_project_1.png
|
||||
.. figure:: img/android_studio_setup_project_1.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
|
@ -21,20 +21,20 @@ which can also be used by CLion.
|
||||
`CMakeLists.txt` file is located there) and select it (but *not* the
|
||||
`CMakeLists.txt` file itself), then click **OK**.
|
||||
|
||||
.. figure:: img/clion_1_open.png
|
||||
.. figure:: img/clion_1_open.png)
|
||||
:align: center
|
||||
|
||||
The folder containing the `CMakeLists.txt` file.
|
||||
|
||||
- If this popup window appears, select **This Window** to open the project:
|
||||
|
||||
.. figure:: img/clion_2_this_window.png
|
||||
.. figure:: img/clion_2_this_window.png)
|
||||
:align: center
|
||||
|
||||
- Choose **Tools > CMake > Change Project Root** from the top menu and select
|
||||
the Godot root folder.
|
||||
|
||||
.. figure:: img/clion_3_change_project_root.png
|
||||
.. figure:: img/clion_3_change_project_root.png)
|
||||
:align: center
|
||||
|
||||
- You should be now be able to see all the project files. Autocomplete should
|
||||
@ -55,12 +55,12 @@ You will first need to `compile godot yourself <https://docs.godotengine.org/en/
|
||||
|
||||
- In CLion, go to **Run > Attach to Process...**
|
||||
|
||||
.. figure:: img/clion_4_select_attach_to_process.png
|
||||
.. figure:: img/clion_4_select_attach_to_process.png)
|
||||
:align: center
|
||||
|
||||
- Find and Select godot in the list (or type the binary name/Process ID)
|
||||
|
||||
.. figure:: img/clion_5_select_godot_process.png
|
||||
.. figure:: img/clion_5_select_godot_process.png)
|
||||
:align: center
|
||||
|
||||
You can now use the debugging tools from CLion.
|
||||
|
@ -10,19 +10,19 @@ Creating a new project
|
||||
|
||||
From Code::Blocks' main screen, click **Create a new project** or select **File > New > Project...**.
|
||||
|
||||
.. figure:: img/code_blocks_file_new_project.png
|
||||
.. figure:: img/code_blocks_file_new_project.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
In the **New from template** window, from **Projects**, select **Empty project**, and click **Go**.
|
||||
|
||||
.. figure:: img/code_blocks_new_empty_project.png
|
||||
.. figure:: img/code_blocks_new_empty_project.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
Click Next, to pass the welcome to the new empty project wizard.
|
||||
|
||||
.. figure:: img/code_blocks_wizard_welcome.png
|
||||
.. figure:: img/code_blocks_wizard_welcome.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -30,13 +30,13 @@ The project file should be created in the root of the cloned project folder. To
|
||||
|
||||
Second, ensure that the **Folder to create project in** is the folder you ran the Git clone command from, not the `godot` project folder. Confirm that the **Resulting filename** field will create the project file in the root of the cloned project folder.
|
||||
|
||||
.. figure:: img/code_blocks_project_title_and_location.png
|
||||
.. figure:: img/code_blocks_project_title_and_location.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
The compiler and configuration settings are managed through **SCons** and will be configured later. However, it's worth deselecting the **Create "Release" configuration** option; so only a single build target is created before clicking **Finish**.
|
||||
|
||||
.. figure:: img/code_blocks_compiler_and_configuration.png
|
||||
.. figure:: img/code_blocks_compiler_and_configuration.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -45,19 +45,19 @@ Configuring the build
|
||||
|
||||
The first step is to change the project properties. Right-click on the new project and select **Properties...**.
|
||||
|
||||
.. figure:: img/code_blocks_open_properties.png
|
||||
.. figure:: img/code_blocks_open_properties.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
Check the **This is a custom Makefile** property. Click OK to save the changes.
|
||||
|
||||
.. figure:: img/code_blocks_project_properties.png
|
||||
.. figure:: img/code_blocks_project_properties.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
The next step is to change the build options. Right-click on the new project and select **Build Options...**.
|
||||
|
||||
.. figure:: img/code_blocks_open_build_options.png
|
||||
.. figure:: img/code_blocks_open_build_options.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -65,17 +65,17 @@ Select the **"Make" commands** tab and remove all the existing commands for all
|
||||
|
||||
If you're using Windows, all the commands need to be preceded with `cmd /c` to iniitalize the command interpreter.
|
||||
|
||||
.. figure:: img/code_blocks_scons_minimum.png
|
||||
.. figure:: img/code_blocks_scons_minimum.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
.. figure:: img/code_blocks_scons_clean.png
|
||||
.. figure:: img/code_blocks_scons_clean.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
Windows example:
|
||||
|
||||
.. figure:: img/code_blocks_scons_windows.png
|
||||
.. figure:: img/code_blocks_scons_windows.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -88,7 +88,7 @@ Once **SCons** has successfully built the desired target, reopen the project **P
|
||||
|
||||
Deselect the **Auto-generate filename prefix** and **Auto-generate filename extension** options.
|
||||
|
||||
.. figure:: img/code_blocks_build_targets.png
|
||||
.. figure:: img/code_blocks_build_targets.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -101,13 +101,13 @@ Adding files to the project
|
||||
|
||||
To add all the Godot code files to the project, right-click on the new project and select **Add files recursively...**.
|
||||
|
||||
.. figure:: img/code_blocks_add_files_recursively.png
|
||||
.. figure:: img/code_blocks_add_files_recursively.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
It should automatically select the project folder; so simply click **Open**. By default, all code files are included, so simply click **OK**.
|
||||
|
||||
.. figure:: img/code_blocks_select_files.png
|
||||
.. figure:: img/code_blocks_select_files.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -116,13 +116,13 @@ Code style configuration
|
||||
|
||||
Before editing any files, remember that all code needs to comply with the `doc_code_style_guidelines`. One important difference with Godot is the use of tabs for indents. Therefore, the key default editor setting that needs to be changed in Code::Blocks is to enable tabs for indents. This setting can be found by selecting **Settings > Editor**.
|
||||
|
||||
.. figure:: img/code_blocks_update_editor_settings.png
|
||||
.. figure:: img/code_blocks_update_editor_settings.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
Under **General Settings**, on the **Editor Settings** tab, under **Tab Options** check **Use TAB character**.
|
||||
|
||||
.. figure:: img/code_block_use_tab_character.png
|
||||
.. figure:: img/code_block_use_tab_character.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
|
@ -10,7 +10,7 @@ Importing the project
|
||||
|
||||
- From the KDevelop's main screen select **Open Project**.
|
||||
|
||||
.. figure:: img/kdevelop_newproject.png
|
||||
.. figure:: img/kdevelop_newproject.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -19,14 +19,14 @@ Importing the project
|
||||
- Navigate to the Godot root folder and select it.
|
||||
- On the next screen, choose **Custom Build System** for the **Project Manager**.
|
||||
|
||||
.. figure:: img/kdevelop_custombuild.png
|
||||
.. figure:: img/kdevelop_custombuild.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
- After the project has been imported, open the project configuration by right-clicking
|
||||
on it in the **Projects** panel and selecting **Open Configuration..** option.
|
||||
|
||||
.. figure:: img/kdevelop_openconfig.png
|
||||
.. figure:: img/kdevelop_openconfig.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -42,7 +42,7 @@ Importing the project
|
||||
platform/<your_platform>/ // Replace <your_platform> with a folder
|
||||
corresponding to your current platform
|
||||
|
||||
.. figure:: img/kdevelop_addincludes.png
|
||||
.. figure:: img/kdevelop_addincludes.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -59,7 +59,7 @@ Importing the project
|
||||
| Arguments | See `doc_introduction_to_the_buildsystem` for a full list of arguments. |
|
||||
+-----------------+------------------------------------------------------------------------------+
|
||||
|
||||
.. figure:: img/kdevelop_buildconfig.png
|
||||
.. figure:: img/kdevelop_buildconfig.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -70,7 +70,7 @@ Debugging the project
|
||||
|
||||
- Select **Run > Configure Launches...** from the top menu.
|
||||
|
||||
.. figure:: img/kdevelop_configlaunches.png
|
||||
.. figure:: img/kdevelop_configlaunches.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -79,7 +79,7 @@ Debugging the project
|
||||
the `<Godot root directory>/bin` folder. The name depends on your build configuration,
|
||||
e.g. `godot.x11.tools.64` for 64-bit X11 platform with `tools` enabled.
|
||||
|
||||
.. figure:: img/kdevelop_configlaunches2.png
|
||||
.. figure:: img/kdevelop_configlaunches2.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
|
@ -10,13 +10,13 @@ Importing the project
|
||||
|
||||
- From the Qt Creator's main screen select **New Project > Import Project > Import Existing Project**.
|
||||
|
||||
.. figure:: img/qtcreator-new-project.png
|
||||
.. figure:: img/qtcreator-new-project.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
- Under **Location** select the Godot root folder.
|
||||
|
||||
.. figure:: img/qtcreator-set-project-path.png
|
||||
.. figure:: img/qtcreator-set-project-path.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -25,14 +25,14 @@ Importing the project
|
||||
`*.glsl` for shader files, `*.py` for buildsystem files,
|
||||
`*.java` for Android platform development, `*.mm` for macOS platform development.
|
||||
|
||||
.. figure:: img/qtcreator-apply-import-filter.png
|
||||
.. figure:: img/qtcreator-apply-import-filter.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
.. note:: You can change this configuration later by right-clicking on your project
|
||||
and selecting the **Edit Files...** option.
|
||||
|
||||
.. figure:: img/qtcreator-edit-files-menu.png
|
||||
.. figure:: img/qtcreator-edit-files-menu.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -41,14 +41,14 @@ Importing the project
|
||||
- Open the `project_name.includes` file and add a line containing `.` to it
|
||||
to correctly enable the code completion.
|
||||
|
||||
.. figure:: img/qtcreator-project-name-includes.png
|
||||
.. figure:: img/qtcreator-project-name-includes.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
- From the left-side menu select **Projects** and open the **Build** tab.
|
||||
- Delete the predefined `make` build step.
|
||||
|
||||
.. figure:: img/qtcreator-projects-build.png
|
||||
.. figure:: img/qtcreator-projects-build.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -61,7 +61,7 @@ Importing the project
|
||||
| Arguments | See `doc_introduction_to_the_buildsystem` for a full list of arguments. |
|
||||
+-----------+------------------------------------------------------------------------------+
|
||||
|
||||
.. figure:: img/qtcreator-set-scons-command.png
|
||||
.. figure:: img/qtcreator-set-scons-command.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -80,7 +80,7 @@ Debugging the project
|
||||
- If you want to run a specific project, specify its root folder under **Working directory**.
|
||||
- If you want to run the editor, add `-e` to the **Command line arguments** field.
|
||||
|
||||
.. figure:: img/qtcreator-run-command.png
|
||||
.. figure:: img/qtcreator-run-command.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -95,7 +95,7 @@ and the IDE should help them follow it. By default, Qt Creator uses spaces
|
||||
for indentation which doesn't match the Godot code style guidelines. You can
|
||||
change this behavior by changing the **Code Style** in **Tools > Options > C++**.
|
||||
|
||||
.. figure:: img/qtcreator-options-cpp.png
|
||||
.. figure:: img/qtcreator-options-cpp.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -103,7 +103,7 @@ Click on **Edit** to change the current settings, then click on
|
||||
**Copy Built-in Code Style** button to set a new code style. Set a name for it
|
||||
(e.g. Godot) and change the Tab policy to be **Tabs Only**.
|
||||
|
||||
.. figure:: img/qtcreator-edit-codestyle.png
|
||||
.. figure:: img/qtcreator-edit-codestyle.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
|
@ -23,7 +23,7 @@ with the solution file, it can be generated using SCons.
|
||||
.. warning:: Visual Studio must be configured with the C++ package. It can be selected
|
||||
in the intaller:
|
||||
|
||||
.. figure:: img/vs_1_install_cpp_package.png
|
||||
.. figure:: img/vs_1_install_cpp_package.png)
|
||||
:align: center
|
||||
|
||||
Debugging the project
|
||||
@ -41,7 +41,7 @@ project manager opens a project, the initial process is terminated and the debug
|
||||
- To configure the launch options to use with the debugger use **Project > Properties**
|
||||
from the top menu:
|
||||
|
||||
.. figure:: img/vs_2_project_properties.png
|
||||
.. figure:: img/vs_2_project_properties.png)
|
||||
:align: center
|
||||
|
||||
- Open the **Debugging** section and under **Command Arguments** add two new arguments:
|
||||
@ -49,7 +49,7 @@ project manager opens a project, the initial process is terminated and the debug
|
||||
tells the executable to open the specified project (must be provided as an *absolute* path
|
||||
to the project root, not the `project.godot` file).
|
||||
|
||||
.. figure:: img/vs_3_debug_command_line.png
|
||||
.. figure:: img/vs_3_debug_command_line.png)
|
||||
:align: center
|
||||
|
||||
To learn more about command line arguments, refer to the
|
||||
@ -61,7 +61,7 @@ process using **Debug > Attach to Process...** menu.
|
||||
To check that everything is working, put a breakpoint in `main.cpp` and press :kbd:`F5` to
|
||||
start debugging.
|
||||
|
||||
.. figure:: img/vs_4_debugging_main.png
|
||||
.. figure:: img/vs_4_debugging_main.png)
|
||||
:align: center
|
||||
|
||||
If you run into any issues, ask for help in one of
|
||||
|
@ -18,17 +18,17 @@ Importing the project
|
||||
**File > Open Folder...**.
|
||||
- Press :kbd:`Ctrl + Shift + P` to open the command prompt window and enter *Configure Task*.
|
||||
|
||||
.. figure:: img/vscode_configure_task.png
|
||||
.. figure:: img/vscode_configure_task.png)
|
||||
:align: center
|
||||
|
||||
- Select the **Create tasks.json file from template** option.
|
||||
|
||||
.. figure:: img/vscode_create_tasksjson.png
|
||||
.. figure:: img/vscode_create_tasksjson.png)
|
||||
:align: center
|
||||
|
||||
- Then select **Others**.
|
||||
|
||||
.. figure:: img/vscode_create_tasksjson_others.png
|
||||
.. figure:: img/vscode_create_tasksjson_others.png)
|
||||
:align: center
|
||||
|
||||
- Within the `tasks.json` file find the `"tasks"` array and add a new section to it:
|
||||
@ -66,7 +66,7 @@ js Windows
|
||||
}
|
||||
```
|
||||
|
||||
.. figure:: img/vscode_3_tasks.json.png
|
||||
.. figure:: img/vscode_3_tasks.json.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -83,7 +83,7 @@ To run and debug the project you need to create a new configuration in the `laun
|
||||
- Press :kbd:`Ctrl + Shift + D` to open the Run panel.
|
||||
- If `launch.json` file is missing you will be prompted to create a new one.
|
||||
|
||||
.. figure:: img/vscode_1_create_launch.json.png
|
||||
.. figure:: img/vscode_1_create_launch.json.png)
|
||||
:align: center
|
||||
|
||||
- Select **C++ (GDB/LLDB)**. There may be another platform specific option here. If selected,
|
||||
@ -159,7 +159,7 @@ js Windows
|
||||
}
|
||||
```
|
||||
|
||||
.. figure:: img/vscode_2_launch.json.png
|
||||
.. figure:: img/vscode_2_launch.json.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
|
@ -11,7 +11,7 @@ Importing the project
|
||||
|
||||
- From Xcode's main screen create a new project using the **Other > External Build System** template.
|
||||
|
||||
.. figure:: img/xcode_1_create_external_build_project.png
|
||||
.. figure:: img/xcode_1_create_external_build_project.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -26,20 +26,20 @@ Importing the project
|
||||
| Directory | A full path to the Godot root folder |
|
||||
+------------+------------------------------------------------------------------------------+
|
||||
|
||||
.. figure:: img/xcode_2_configure_scons.png
|
||||
.. figure:: img/xcode_2_configure_scons.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
- Add a Command Line Tool target which will be used for indexing the project by
|
||||
choosing **File > New > Target...**.
|
||||
|
||||
.. figure:: img/xcode_3_add_new_target.png
|
||||
.. figure:: img/xcode_3_add_new_target.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
- Select **OS X > Application > Command Line Tool**.
|
||||
|
||||
.. figure:: img/xcode_4_select_command_line_target.png
|
||||
.. figure:: img/xcode_4_select_command_line_target.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -53,14 +53,14 @@ Importing the project
|
||||
- Add the Godot source to the project by dragging and dropping it into the project file browser.
|
||||
- Uncheck **Create external build system project**.
|
||||
|
||||
.. figure:: img/xcode_5_after_add_godot_source_to_project.png
|
||||
.. figure:: img/xcode_5_after_add_godot_source_to_project.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
- Next select **Create groups** for the **Added folders** option and check *only*
|
||||
your command line indexing target in the **Add to targets** section.
|
||||
|
||||
.. figure:: img/xcode_6_after_add_godot_source_to_project_2.png
|
||||
.. figure:: img/xcode_6_after_add_godot_source_to_project_2.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -84,7 +84,7 @@ To enable debugging support you need to edit the external build target's build a
|
||||
|
||||
ln -f ${PROJECT_DIR}/godot/bin/godot.osx.tools.64 ${PROJECT_DIR}/godot/bin/godot
|
||||
|
||||
.. figure:: img/xcode_7_setup_build_post_action.png
|
||||
.. figure:: img/xcode_7_setup_build_post_action.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
@ -92,7 +92,7 @@ To enable debugging support you need to edit the external build target's build a
|
||||
|
||||
- Open the scheme editor again and select **Run**.
|
||||
|
||||
.. figure:: img/xcode_8_setup_run_scheme.png
|
||||
.. figure:: img/xcode_8_setup_run_scheme.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
|
||||
|
@ -4,26 +4,26 @@ Inheritance class tree
|
||||
Object
|
||||
------
|
||||
|
||||
.. image:: img/Object.png
|
||||
![](img/Object.png)
|
||||
|
||||
Reference
|
||||
---------
|
||||
|
||||
.. image:: img/Reference.png
|
||||
![](img/Reference.png)
|
||||
|
||||
Control
|
||||
-------
|
||||
|
||||
.. image:: img/Control.png
|
||||
![](img/Control.png)
|
||||
|
||||
Node2D
|
||||
------
|
||||
|
||||
.. image:: img/Node2D.png
|
||||
![](img/Node2D.png)
|
||||
|
||||
Spatial
|
||||
-------
|
||||
|
||||
.. image:: img/Spatial.png
|
||||
![](img/Spatial.png)
|
||||
|
||||
Source files: :download:`tree.zip <files/class_tree.zip>`.
|
||||
|
@ -14,7 +14,7 @@ The following diagram describes the architecture used by Godot, from the
|
||||
core components down to the abstracted drivers, via the scene
|
||||
structure and the servers.
|
||||
|
||||
.. image:: img/architecture_diagram.jpg
|
||||
![](img/architecture_diagram.jpg
|
||||
|
||||
Debugging the editor with gdb
|
||||
-----------------------------
|
||||
|
@ -72,7 +72,7 @@ VerySleepy
|
||||
will spawn a child process for every project edited or run.
|
||||
- Open VerySleepy and select the Godot executable in the list of processes on the left:
|
||||
|
||||
.. image:: img/cpp_profiler_verysleepy_select_process.png
|
||||
![](img/cpp_profiler_verysleepy_select_process.png)
|
||||
|
||||
- Click the **Profile All** button on the right to start profiling.
|
||||
- Perform the actions you wish to profile in the editor or project. When you're done, click **Stop** (*not* Abort).
|
||||
@ -83,14 +83,14 @@ VerySleepy
|
||||
**Filter Module to <Godot executable name>** in the dropdown that appears.
|
||||
- Your results window should now look something like this:
|
||||
|
||||
.. image:: img/cpp_profiler_verysleepy_results_filtered.png
|
||||
![](img/cpp_profiler_verysleepy_results_filtered.png)
|
||||
|
||||
HotSpot
|
||||
^^^^^^^
|
||||
|
||||
- Open HotSpot. Click **Record Data**:
|
||||
|
||||
.. image:: img/cpp_profiler_hotspot_welcome.png
|
||||
![](img/cpp_profiler_hotspot_welcome.png)
|
||||
|
||||
- In the next window, specify the path to the Godot binary that includes debug symbols.
|
||||
- Specify command line arguments to run a specific project, with or without the editor.
|
||||
@ -102,7 +102,7 @@ HotSpot
|
||||
Otherwise, some events may be missing in the capture.
|
||||
Your settings should now look something like this:
|
||||
|
||||
.. image:: img/cpp_profiler_hotspot_record.png
|
||||
![](img/cpp_profiler_hotspot_record.png)
|
||||
|
||||
- Click **Start Recording** and perform the actions you wish to profile in the editor/project.
|
||||
- Quit the editor/project normally or use the **Stop Profiling** button in HotSpot
|
||||
@ -110,7 +110,7 @@ HotSpot
|
||||
if you're not interested in the engine's quit procedure.
|
||||
- Click **View Results** and wait for the profiling visualization to be generated:
|
||||
|
||||
.. image:: img/cpp_profiler_hotspot_view_results.png
|
||||
![](img/cpp_profiler_hotspot_view_results.png)
|
||||
|
||||
- Use the tabs at the top to navigate between the different views. These views
|
||||
show the same data, but in different ways. The **Flame Graph** tab is a good
|
||||
@ -121,7 +121,7 @@ HotSpot
|
||||
started by the engine among with the CPU utilization for each thread.
|
||||
This lets you see threads that can be a bottleneck at a given point in time.
|
||||
|
||||
.. image:: img/cpp_profiler_hotspot_flame_graph.png
|
||||
![](img/cpp_profiler_hotspot_flame_graph.png)
|
||||
|
||||
.. note::
|
||||
|
||||
@ -138,20 +138,20 @@ Xcode Instruments
|
||||
- Open Xcode. Select **Open Developer Tool** - **Instruments** from the **Xcode** app menu:
|
||||
- Double-click on **Time Profiler** in the **Instruments** window:
|
||||
|
||||
.. image:: img/cpp_profiler_xcode_menu.png
|
||||
![](img/cpp_profiler_xcode_menu.png)
|
||||
|
||||
- In the Time Profiler window, click on the **Target** menu, select **Choose target...**
|
||||
and specify the path to the Godot binary, command line arguments and environment variables
|
||||
in the next window.
|
||||
|
||||
.. image:: img/cpp_profiler_time_profiler.png
|
||||
![](img/cpp_profiler_time_profiler.png)
|
||||
|
||||
- You can also attach the Time Profiler to a running process by selecting it from the **Target**
|
||||
menu.
|
||||
|
||||
- Click the **Start an immediate mode recording** button to start profiling.
|
||||
|
||||
.. image:: img/cpp_profiler_time_profiler_record.png
|
||||
![](img/cpp_profiler_time_profiler_record.png)
|
||||
|
||||
- Perform the actions you wish to profile in the editor or project. When you're done,
|
||||
click the **Stop** button.
|
||||
@ -163,4 +163,4 @@ Xcode Instruments
|
||||
remove external modules.
|
||||
- You can use the timeline at the top of the window to display details for the specific time period.
|
||||
|
||||
.. image:: img/cpp_profiler_time_profiler_result.png
|
||||
![](img/cpp_profiler_time_profiler_result.png)
|
||||
|
@ -7,7 +7,7 @@ In this short first part, we'll set up and organize the project.
|
||||
|
||||
Launch Godot and create a new project.
|
||||
|
||||
.. image:: img/new-project-button.png
|
||||
![](img/new-project-button.png)
|
||||
|
||||
GDScript
|
||||
|
||||
@ -20,20 +20,20 @@ GDScript
|
||||
|
||||
Your project folder should look like this.
|
||||
|
||||
.. image:: img/folder-content.png
|
||||
![](img/folder-content.png)
|
||||
|
||||
This game is designed for portrait mode, so we need to adjust the size of the
|
||||
game window. Click on *Project -> Project Settings* to open the project settings
|
||||
window and in the left column, open the *Display -> Window* tab. There, set
|
||||
"Width" to `480` and "Height" to `720`.
|
||||
|
||||
.. image:: img/setting-project-width-and-height.png
|
||||
![](img/setting-project-width-and-height.png)
|
||||
|
||||
Also, scroll down to the bottom of the section and, under the "Stretch" options,
|
||||
set `Mode` to "2d" and `Aspect` to "keep". This ensures that the game scales
|
||||
consistently on different sized screens.
|
||||
|
||||
.. image:: img/setting-stretch-mode.png
|
||||
![](img/setting-stretch-mode.png)
|
||||
|
||||
Organizing the project
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -46,6 +46,6 @@ scenes and their scripts, but for this relatively small game, you can save your
|
||||
scenes and scripts in the project's root folder, identified by `res://`. You
|
||||
can see your project folders in the FileSystem dock in the lower left corner:
|
||||
|
||||
.. image:: img/filesystem_dock.png
|
||||
![](img/filesystem_dock.png)
|
||||
|
||||
With the project in place, we're ready to design the player scene in the next lesson.
|
||||
|
@ -18,7 +18,7 @@ rule, a scene's root node should reflect the object's desired functionality -
|
||||
what the object *is*. Click the "Other Node" button and add an `Area2D
|
||||
<class_Area2D>` node to the scene.
|
||||
|
||||
.. image:: img/add_node.png
|
||||
![](img/add_node.png)
|
||||
|
||||
Godot will display a warning icon next to the node in the scene tree. You can
|
||||
ignore it for now. We will address it later.
|
||||
@ -33,7 +33,7 @@ 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 "Makes sure the object's
|
||||
children are not selectable."
|
||||
|
||||
.. image:: img/lock_children.png
|
||||
![](img/lock_children.png)
|
||||
|
||||
Save the scene. Click Scene -> Save, or press :kbd:`Ctrl + S` on Windows/Linux
|
||||
or :kbd:`Cmd + S` on macOS.
|
||||
@ -61,7 +61,7 @@ next to the node. An `AnimatedSprite` requires a `SpriteFrames
|
||||
display. To create one, find the `Frames` property in the Inspector and click
|
||||
"[empty]" -> "New SpriteFrames". Click again to open the "SpriteFrames" panel:
|
||||
|
||||
.. image:: img/spriteframes_panel.png
|
||||
![](img/spriteframes_panel.png)
|
||||
|
||||
|
||||
On the left is a list of animations. Click the "default" one and rename it to
|
||||
@ -71,14 +71,14 @@ 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"
|
||||
side of the panel for the corresponding animation:
|
||||
|
||||
.. image:: img/spriteframes_panel2.png
|
||||
![](img/spriteframes_panel2.png)
|
||||
|
||||
The player images are a bit too large for the game window, so we need to scale
|
||||
them down. Click on the `AnimatedSprite` node and set the `Scale` property
|
||||
to `(0.5, 0.5)`. You can find it in the Inspector under the `Node2D`
|
||||
heading.
|
||||
|
||||
.. image:: img/player_scale.png
|
||||
![](img/player_scale.png)
|
||||
|
||||
Finally, add a `CollisionShape2D` as a child of
|
||||
`Player`. This will determine the player's "hitbox", or the bounds of its
|
||||
@ -87,11 +87,11 @@ fit, so next to "Shape" in the Inspector, click "[empty]"" -> "New
|
||||
CapsuleShape2D". Using the two size handles, resize the shape to cover the
|
||||
sprite:
|
||||
|
||||
.. image:: img/player_coll_shape.png
|
||||
![](img/player_coll_shape.png)
|
||||
|
||||
When you're finished, your `Player` scene should look like this:
|
||||
|
||||
.. image:: img/player_scene_nodes.png
|
||||
![](img/player_scene_nodes.png)
|
||||
|
||||
Make sure to save the scene again after these changes.
|
||||
|
||||
|
@ -10,7 +10,7 @@ To do so, we need to add some functionality that we can't get from a built-in
|
||||
node, so we'll add a script. Click the `Player` node and click the "Attach
|
||||
Script" button:
|
||||
|
||||
.. image:: img/add_script_button.png
|
||||
![](img/add_script_button.png)
|
||||
|
||||
In the script settings window, you can leave the default settings alone. Just
|
||||
click "Create":
|
||||
@ -18,7 +18,7 @@ click "Create":
|
||||
.. note:: If you're creating a C# script or other languages, select the language
|
||||
from the `language` drop down menu before hitting create.
|
||||
|
||||
.. image:: img/attach_node_window.png
|
||||
![](img/attach_node_window.png)
|
||||
|
||||
.. note:: If this is your first time encountering GDScript, please read
|
||||
`doc_scripting` before continuing.
|
||||
@ -41,7 +41,7 @@ node and you'll see the property now appears in the "Script Variables" section
|
||||
of the Inspector. Remember, if you change the value here, it will override the
|
||||
value written in the script.
|
||||
|
||||
.. image:: img/export_variable.png
|
||||
![](img/export_variable.png)
|
||||
|
||||
The `_ready()` function is called when a node enters the scene tree, which is
|
||||
a good time to find the size of the game window:
|
||||
@ -70,13 +70,13 @@ Click on *Project -> Project Settings* to open the project settings window and
|
||||
click on the *Input Map* tab at the top. Type "move_right" in the top bar and
|
||||
click the "Add" button to add the `move_right` action.
|
||||
|
||||
.. image:: img/input-mapping-add-action.png
|
||||
![](img/input-mapping-add-action.png)
|
||||
|
||||
We need to assign a key to this action. Click the "+" icon on the right, then
|
||||
click the "Key" option in the drop-down menu. A dialog asks you to type in the
|
||||
desired key. Press the right arrow on your keyboard and click "Ok".
|
||||
|
||||
.. image:: img/input-mapping-add-key.png
|
||||
![](img/input-mapping-add-key.png)
|
||||
|
||||
Repeat these steps to add three more mappings:
|
||||
|
||||
@ -86,7 +86,7 @@ Repeat these steps to add three more mappings:
|
||||
|
||||
Your input map tab should look like this:
|
||||
|
||||
.. image:: img/input-mapping-completed.png
|
||||
![](img/input-mapping-completed.png)
|
||||
|
||||
Click the "Close" button to close the project settings.
|
||||
|
||||
@ -249,7 +249,7 @@ This defines a custom signal called "hit" that we will have our player emit
|
||||
collision. Select the `Player` node and click the "Node" tab next to the
|
||||
Inspector tab to see the list of signals the player can emit:
|
||||
|
||||
.. image:: img/player_signals.png
|
||||
![](img/player_signals.png)
|
||||
|
||||
Notice our custom "hit" signal is there as well! Since our enemies are going to
|
||||
be `RigidBody2D` nodes, we want the `body_entered(body: Node)` signal. This
|
||||
@ -258,7 +258,7 @@ the "Connect a Signal" window appears. We don't need to change any of these
|
||||
settings so click "Connect" again. Godot will automatically create a function in
|
||||
your player's script.
|
||||
|
||||
.. image:: img/player_signal_connection.png
|
||||
![](img/player_signal_connection.png)
|
||||
|
||||
Note the green icon indicating that a signal is connected to this function. Add
|
||||
this code to the function:
|
||||
|
@ -29,7 +29,7 @@ to `0`, so the mob will not fall downward. In addition, under the
|
||||
`CollisionObject2D` section, click the `Mask` property and uncheck the first
|
||||
box. This will ensure the mobs do not collide with each other.
|
||||
|
||||
.. image:: img/set_collision_mask.png
|
||||
![](img/set_collision_mask.png)
|
||||
|
||||
Set up the `AnimatedSprite` like you did for the
|
||||
player. This time, we have 3 animations: `fly`, `swim`, and `walk`. There
|
||||
@ -37,7 +37,7 @@ are two images for each animation in the art folder.
|
||||
|
||||
Adjust the "Speed (FPS)" to `3` for all animations.
|
||||
|
||||
.. image:: img/mob_animations.gif
|
||||
![](img/mob_animations.gif)
|
||||
|
||||
Set the `Playing` property in the Inspector to "On".
|
||||
|
||||
|
@ -12,7 +12,7 @@ be a container for handling game logic. It does not require 2D functionality its
|
||||
Click the **Instance** button (represented by a chain link icon) and select your saved
|
||||
`Player.tscn`.
|
||||
|
||||
.. image:: img/instance_scene.png
|
||||
![](img/instance_scene.png)
|
||||
|
||||
Now, add the following nodes as children of `Main`, and name them as shown
|
||||
(values are in seconds):
|
||||
@ -43,7 +43,7 @@ location on the edge of the screen. Add a `Path2D` node
|
||||
named `MobPath` as a child of `Main`. When you select `Path2D`, you will
|
||||
see some new buttons at the top of the editor:
|
||||
|
||||
.. image:: img/path2d_buttons.png
|
||||
![](img/path2d_buttons.png)
|
||||
|
||||
Select the middle one ("Add Point") and draw the path by clicking to add the
|
||||
points at the corners shown. To have the points snap to the grid, make sure "Use
|
||||
@ -51,12 +51,12 @@ Grid Snap" and "Use Snap" are both selected. These options can be found to the
|
||||
left of the "Lock" button, appearing as a magnet next to some dots and
|
||||
intersecting lines, respectively.
|
||||
|
||||
.. image:: img/grid_snap_button.png
|
||||
![](img/grid_snap_button.png)
|
||||
|
||||
.. important:: Draw the path in *clockwise* order, or your mobs will spawn
|
||||
pointing *outwards* instead of *inwards*!
|
||||
|
||||
.. image:: img/draw_path2d.gif
|
||||
![](img/draw_path2d.gif)
|
||||
|
||||
After placing point `4` in the image, click the "Close Curve" button and your
|
||||
curve will be complete.
|
||||
@ -68,7 +68,7 @@ a random position and direction along the path.
|
||||
|
||||
Your scene should look like this:
|
||||
|
||||
.. image:: img/main_scene_nodes.png
|
||||
![](img/main_scene_nodes.png)
|
||||
|
||||
Main script
|
||||
~~~~~~~~~~~
|
||||
|
@ -38,16 +38,16 @@ well. There is a font file included in the game assets called
|
||||
|
||||
1. Under **Theme overrides > Fonts** click on the empty box and select "New DynamicFont"
|
||||
|
||||
.. image:: img/custom_font1.png
|
||||
![](img/custom_font1.png)
|
||||
|
||||
2. Click on the "DynamicFont" you added, and under **Font > FontData**,
|
||||
choose "Load" and select the "Xolonium-Regular.ttf" file.
|
||||
|
||||
.. image:: img/custom_font2.png
|
||||
![](img/custom_font2.png)
|
||||
|
||||
Set the "Size" property under `Settings`, `64` works well.
|
||||
|
||||
.. image:: img/custom_font3.png
|
||||
![](img/custom_font3.png)
|
||||
|
||||
Once you've done this on the `ScoreLabel`, you can click the down arrow next
|
||||
to the Font property and choose "Copy", then "Paste" it in the same place
|
||||
@ -62,7 +62,7 @@ on the other two Control nodes.
|
||||
Arrange the nodes as shown below. Click the "Layout" button to set a Control
|
||||
node's layout:
|
||||
|
||||
.. image:: img/ui_anchor.png
|
||||
![](img/ui_anchor.png)
|
||||
|
||||
You can drag the nodes to place them manually, or for more precise placement,
|
||||
use the following settings:
|
||||
@ -174,7 +174,7 @@ Now that we're done creating the `HUD` scene, go back to `Main`. Instance
|
||||
the `HUD` scene in `Main` like you did the `Player` scene. The scene tree
|
||||
should look like this, so make sure you didn't miss anything:
|
||||
|
||||
.. image:: img/completed_main_scene.png
|
||||
![](img/completed_main_scene.png)
|
||||
|
||||
Now we need to connect the `HUD` functionality to our `Main` script. This
|
||||
requires a few additions to the `Main` scene:
|
||||
@ -225,7 +225,7 @@ 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".
|
||||
|
||||
.. image:: img/group_tab.png
|
||||
![](img/group_tab.png)
|
||||
|
||||
Now all mobs will be in the "mobs" group. We can then add the following line to
|
||||
the `new_game()` function in `Main`:
|
||||
|
@ -59,14 +59,14 @@ item. A second *Shortcut* property will appear. Select "New InputEventAction"
|
||||
and click the new "InputEventAction". Finally, in the *Action* property, type
|
||||
the name `start_game`.
|
||||
|
||||
.. image:: img/start_button_shortcut.png
|
||||
![](img/start_button_shortcut.png)
|
||||
|
||||
Now when the start button appears, you can either click it or press :kbd:`Enter`
|
||||
to start the game.
|
||||
|
||||
And with that, you completed your first 2D game in Godot.
|
||||
|
||||
.. image:: img/dodge_preview.gif
|
||||
![](img/dodge_preview.gif)
|
||||
|
||||
You got to make a player-controlled character, enemies that spawn randomly
|
||||
around the game board, count the score, implement a game over and replay, user
|
||||
|
@ -73,4 +73,4 @@ Contents
|
||||
06.heads_up_display
|
||||
07.finishing-up
|
||||
|
||||
.. |image0| image:: img/dodge_preview.gif
|
||||
.. |image0| image:: img/dodge_preview.gif)
|
||||
|
@ -145,20 +145,20 @@ At this point, your project should look like this.
|
||||
That's our starting point. In the next part, we will work on the player scene
|
||||
and base movement.
|
||||
|
||||
.. |image1| image:: img/01.game_setup/01.import_button.png
|
||||
.. |image2| image:: img/01.game_setup/02.browse_to_project_folder.png
|
||||
.. |image3| image:: img/01.game_setup/03.import_and_edit.png
|
||||
.. |image4| image:: img/01.game_setup/04.start_assets.png
|
||||
.. |image5| image:: img/01.game_setup/05.main_node.png
|
||||
.. |image6| image:: img/01.game_setup/06.staticbody_node.png
|
||||
.. |image7| image:: img/01.game_setup/07.collision_shape_warning.png
|
||||
.. |image8| image:: img/01.game_setup/08.create_box_shape.png
|
||||
.. |image9| image:: img/01.game_setup/09.box_extents.png
|
||||
.. |image10| image:: img/01.game_setup/10.mesh_instance.png
|
||||
.. |image11| image:: img/01.game_setup/11.cube_mesh.png
|
||||
.. |image12| image:: img/01.game_setup/12.cube_resized.png
|
||||
.. |image13| image:: img/01.game_setup/13.move_gizmo_y_axis.png
|
||||
.. |image14| image:: img/01.game_setup/14.select_mode_icon.png
|
||||
.. |image15| image:: img/01.game_setup/15.translation_amount.png
|
||||
.. |image16| image:: img/01.game_setup/16.turn_on_shadows.png
|
||||
.. |image17| image:: img/01.game_setup/17.project_with_light.png
|
||||
.. |image1| image:: img/01.game_setup/01.import_button.png)
|
||||
.. |image2| image:: img/01.game_setup/02.browse_to_project_folder.png)
|
||||
.. |image3| image:: img/01.game_setup/03.import_and_edit.png)
|
||||
.. |image4| image:: img/01.game_setup/04.start_assets.png)
|
||||
.. |image5| image:: img/01.game_setup/05.main_node.png)
|
||||
.. |image6| image:: img/01.game_setup/06.staticbody_node.png)
|
||||
.. |image7| image:: img/01.game_setup/07.collision_shape_warning.png)
|
||||
.. |image8| image:: img/01.game_setup/08.create_box_shape.png)
|
||||
.. |image9| image:: img/01.game_setup/09.box_extents.png)
|
||||
.. |image10| image:: img/01.game_setup/10.mesh_instance.png)
|
||||
.. |image11| image:: img/01.game_setup/11.cube_mesh.png)
|
||||
.. |image12| image:: img/01.game_setup/12.cube_resized.png)
|
||||
.. |image13| image:: img/01.game_setup/13.move_gizmo_y_axis.png)
|
||||
.. |image14| image:: img/01.game_setup/14.select_mode_icon.png)
|
||||
.. |image15| image:: img/01.game_setup/15.translation_amount.png)
|
||||
.. |image16| image:: img/01.game_setup/16.turn_on_shadows.png)
|
||||
.. |image17| image:: img/01.game_setup/17.project_with_light.png)
|
||||
|
@ -8,7 +8,7 @@ actions, and code player movement. By the end, you'll have a playable character
|
||||
that moves in eight directions.
|
||||
|
||||
.. TODO: add player animated gif?
|
||||
.. player_movement.gif
|
||||
.. player_movement.gif)
|
||||
|
||||
Create a new scene by going to the Scene menu in the top-left and clicking *New
|
||||
Scene*. Create a *KinematicBody* node as the root and name it *Player*.
|
||||
@ -156,22 +156,22 @@ groups of keys and buttons in your projects.
|
||||
|
||||
In the next part, we'll code and test the player's movement.
|
||||
|
||||
.. |image0| image:: img/02.player_input/01.new_scene.png
|
||||
.. |image1| image:: img/02.player_input/02.instantiating_the_model.png
|
||||
.. |image2| image:: img/02.player_input/03.scene_structure.png
|
||||
.. |image3| image:: img/02.player_input/04.sphere_shape.png
|
||||
.. |image4| image:: img/02.player_input/05.moving_the_sphere_up.png
|
||||
.. |image5| image:: img/02.player_input/06.toggling_visibility.png
|
||||
.. |image6| image:: img/02.player_input/07.project_settings.png
|
||||
.. |image7| image:: img/02.player_input/07.input_map_tab.png
|
||||
.. |image8| image:: img/02.player_input/07.adding_action.png
|
||||
.. |image9| image:: img/02.player_input/08.actions_list_empty.png
|
||||
.. |image10| image:: img/02.player_input/08.create_key_action.png
|
||||
.. |image11| image:: img/02.player_input/09.keyboard_key_popup.png
|
||||
.. |image12| image:: img/02.player_input/09.keyboard_keys.png
|
||||
.. |image13| image:: img/02.player_input/10.joy_axis_option.png
|
||||
.. |image14| image:: img/02.player_input/11.joy_axis_popup.png
|
||||
.. |image15| image:: img/02.player_input/12.move_inputs_mapped.png
|
||||
.. |image16| image:: img/02.player_input/13.joy_button_option.png
|
||||
.. |image17| image:: img/02.player_input/14.add_jump_button.png
|
||||
.. |image18| image:: img/02.player_input/14.jump_input_action.png
|
||||
.. |image0| image:: img/02.player_input/01.new_scene.png)
|
||||
.. |image1| image:: img/02.player_input/02.instantiating_the_model.png)
|
||||
.. |image2| image:: img/02.player_input/03.scene_structure.png)
|
||||
.. |image3| image:: img/02.player_input/04.sphere_shape.png)
|
||||
.. |image4| image:: img/02.player_input/05.moving_the_sphere_up.png)
|
||||
.. |image5| image:: img/02.player_input/06.toggling_visibility.png)
|
||||
.. |image6| image:: img/02.player_input/07.project_settings.png)
|
||||
.. |image7| image:: img/02.player_input/07.input_map_tab.png)
|
||||
.. |image8| image:: img/02.player_input/07.adding_action.png)
|
||||
.. |image9| image:: img/02.player_input/08.actions_list_empty.png)
|
||||
.. |image10| image:: img/02.player_input/08.create_key_action.png)
|
||||
.. |image11| image:: img/02.player_input/09.keyboard_key_popup.png)
|
||||
.. |image12| image:: img/02.player_input/09.keyboard_keys.png)
|
||||
.. |image13| image:: img/02.player_input/10.joy_axis_option.png)
|
||||
.. |image14| image:: img/02.player_input/11.joy_axis_popup.png)
|
||||
.. |image15| image:: img/02.player_input/12.move_inputs_mapped.png)
|
||||
.. |image16| image:: img/02.player_input/13.joy_button_option.png)
|
||||
.. |image17| image:: img/02.player_input/14.add_jump_button.png)
|
||||
.. |image18| image:: img/02.player_input/14.jump_input_action.png)
|
||||
|
@ -279,14 +279,14 @@ the ground should fill the background.
|
||||
With that, we have both player movement and the view in place. Next, we will
|
||||
work on the monsters.
|
||||
|
||||
.. |image0| image:: img/03.player_movement_code/01.attach_script_to_player.png
|
||||
.. |image1| image:: img/03.player_movement_code/02.clicking_main_tab.png
|
||||
.. |image2| image:: img/03.player_movement_code/03.instance_child_scene.png
|
||||
.. |image3| image:: img/03.player_movement_code/04.scene_tree_with_camera.png
|
||||
.. |image4| image:: img/03.player_movement_code/05.camera_preview_checkbox.png
|
||||
.. |image5| image:: img/03.player_movement_code/06.two_viewports.png
|
||||
.. |image6| image:: img/03.player_movement_code/07.camera_preview_checkbox.png
|
||||
.. |image7| image:: img/03.player_movement_code/08.camera_moved.png
|
||||
.. |image8| image:: img/03.player_movement_code/09.camera_rotated.png
|
||||
.. |image9| image:: img/03.player_movement_code/10.camera_perspective.png
|
||||
.. |image10| image:: img/03.player_movement_code/11.camera_orthographic.png
|
||||
.. |image0| image:: img/03.player_movement_code/01.attach_script_to_player.png)
|
||||
.. |image1| image:: img/03.player_movement_code/02.clicking_main_tab.png)
|
||||
.. |image2| image:: img/03.player_movement_code/03.instance_child_scene.png)
|
||||
.. |image3| image:: img/03.player_movement_code/04.scene_tree_with_camera.png)
|
||||
.. |image4| image:: img/03.player_movement_code/05.camera_preview_checkbox.png)
|
||||
.. |image5| image:: img/03.player_movement_code/06.two_viewports.png)
|
||||
.. |image6| image:: img/03.player_movement_code/07.camera_preview_checkbox.png)
|
||||
.. |image7| image:: img/03.player_movement_code/08.camera_moved.png)
|
||||
.. |image8| image:: img/03.player_movement_code/09.camera_rotated.png)
|
||||
.. |image9| image:: img/03.player_movement_code/10.camera_perspective.png)
|
||||
.. |image10| image:: img/03.player_movement_code/11.camera_orthographic.png)
|
||||
|
@ -236,14 +236,14 @@ gdscript GDScript
|
||||
queue_free()
|
||||
```
|
||||
|
||||
.. |image0| image:: img/04.mob_scene/01.initial_three_nodes.png
|
||||
.. |image1| image:: img/04.mob_scene/02.add_child_node.png
|
||||
.. |image2| image:: img/04.mob_scene/03.scene_with_collision_shape.png
|
||||
.. |image3| image:: img/04.mob_scene/04.create_box_shape.png
|
||||
.. |image4| image:: img/04.mob_scene/05.box_final_size.png
|
||||
.. |image5| image:: img/04.mob_scene/06.visibility_notifier.png
|
||||
.. |image6| image:: img/04.mob_scene/07.visibility_notifier_bbox_resized.png
|
||||
.. |image7| image:: img/04.mob_scene/08.mob_attach_script.png
|
||||
.. |image8| image:: img/04.mob_scene/09.switch_to_3d_workspace.png
|
||||
.. |image9| image:: img/04.mob_scene/10.node_dock.png
|
||||
.. |image10| image:: img/04.mob_scene/11.connect_signal.png
|
||||
.. |image0| image:: img/04.mob_scene/01.initial_three_nodes.png)
|
||||
.. |image1| image:: img/04.mob_scene/02.add_child_node.png)
|
||||
.. |image2| image:: img/04.mob_scene/03.scene_with_collision_shape.png)
|
||||
.. |image3| image:: img/04.mob_scene/04.create_box_shape.png)
|
||||
.. |image4| image:: img/04.mob_scene/05.box_final_size.png)
|
||||
.. |image5| image:: img/04.mob_scene/06.visibility_notifier.png)
|
||||
.. |image6| image:: img/04.mob_scene/07.visibility_notifier_bbox_resized.png)
|
||||
.. |image7| image:: img/04.mob_scene/08.mob_attach_script.png)
|
||||
.. |image8| image:: img/04.mob_scene/09.switch_to_3d_workspace.png)
|
||||
.. |image9| image:: img/04.mob_scene/10.node_dock.png)
|
||||
.. |image10| image:: img/04.mob_scene/11.connect_signal.png)
|
||||
|
@ -268,29 +268,29 @@ move in a straight line.
|
||||
For now, they bump and slide against one another when their paths cross. We'll
|
||||
address this in the next part.
|
||||
|
||||
.. |image0| image:: img/05.spawning_mobs/01.monsters_path_preview.png
|
||||
.. |image1| image:: img/05.spawning_mobs/02.project_settings.png
|
||||
.. |image2| image:: img/05.spawning_mobs/03.window_settings.png
|
||||
.. |image3| image:: img/05.spawning_mobs/04.camera_preview.png
|
||||
.. |image4| image:: img/05.spawning_mobs/05.cylinders_node.png
|
||||
.. |image5| image:: img/05.spawning_mobs/06.cylinder_mesh.png
|
||||
.. |image6| image:: img/05.spawning_mobs/07.top_view.png
|
||||
.. |image7| image:: img/05.spawning_mobs/08.toggle_view_grid.png
|
||||
.. |image8| image:: img/05.spawning_mobs/09.toggle_grid_snap.png
|
||||
.. |image9| image:: img/05.spawning_mobs/10.place_first_cylinder.png
|
||||
.. |image10| image:: img/05.spawning_mobs/11.both_cylinders_selected.png
|
||||
.. |image11| image:: img/05.spawning_mobs/12.four_cylinders.png
|
||||
.. |image12| image:: img/05.spawning_mobs/13.selecting_all_cylinders.png
|
||||
.. |image13| image:: img/05.spawning_mobs/14.spatial_material.png
|
||||
.. |image14| image:: img/05.spawning_mobs/15.bright-cylinders.png
|
||||
.. |image15| image:: img/05.spawning_mobs/16.cylinders_fold.png
|
||||
.. |image16| image:: img/05.spawning_mobs/17.points_options.png
|
||||
.. |image17| image:: img/05.spawning_mobs/18.close_path.png
|
||||
.. |image18| image:: img/05.spawning_mobs/19.path_result.png
|
||||
.. |image19| image:: img/05.spawning_mobs/20.spawn_nodes.png
|
||||
.. |image20| image:: img/05.spawning_mobs/20.mob_scene_property.png
|
||||
.. |image21| image:: img/05.spawning_mobs/21.mob_timer.png
|
||||
.. |image22| image:: img/05.spawning_mobs/22.mob_timer_properties.png
|
||||
.. |image23| image:: img/05.spawning_mobs/23.timeout_signal.png
|
||||
.. |image24| image:: img/05.spawning_mobs/24.connect_timer_to_main.png
|
||||
.. |image25| image:: img/05.spawning_mobs/25.spawn_result.png
|
||||
.. |image0| image:: img/05.spawning_mobs/01.monsters_path_preview.png)
|
||||
.. |image1| image:: img/05.spawning_mobs/02.project_settings.png)
|
||||
.. |image2| image:: img/05.spawning_mobs/03.window_settings.png)
|
||||
.. |image3| image:: img/05.spawning_mobs/04.camera_preview.png)
|
||||
.. |image4| image:: img/05.spawning_mobs/05.cylinders_node.png)
|
||||
.. |image5| image:: img/05.spawning_mobs/06.cylinder_mesh.png)
|
||||
.. |image6| image:: img/05.spawning_mobs/07.top_view.png)
|
||||
.. |image7| image:: img/05.spawning_mobs/08.toggle_view_grid.png)
|
||||
.. |image8| image:: img/05.spawning_mobs/09.toggle_grid_snap.png)
|
||||
.. |image9| image:: img/05.spawning_mobs/10.place_first_cylinder.png)
|
||||
.. |image10| image:: img/05.spawning_mobs/11.both_cylinders_selected.png)
|
||||
.. |image11| image:: img/05.spawning_mobs/12.four_cylinders.png)
|
||||
.. |image12| image:: img/05.spawning_mobs/13.selecting_all_cylinders.png)
|
||||
.. |image13| image:: img/05.spawning_mobs/14.spatial_material.png)
|
||||
.. |image14| image:: img/05.spawning_mobs/15.bright-cylinders.png)
|
||||
.. |image15| image:: img/05.spawning_mobs/16.cylinders_fold.png)
|
||||
.. |image16| image:: img/05.spawning_mobs/17.points_options.png)
|
||||
.. |image17| image:: img/05.spawning_mobs/18.close_path.png)
|
||||
.. |image18| image:: img/05.spawning_mobs/19.path_result.png)
|
||||
.. |image19| image:: img/05.spawning_mobs/20.spawn_nodes.png)
|
||||
.. |image20| image:: img/05.spawning_mobs/20.mob_scene_property.png)
|
||||
.. |image21| image:: img/05.spawning_mobs/21.mob_timer.png)
|
||||
.. |image22| image:: img/05.spawning_mobs/22.mob_timer_properties.png)
|
||||
.. |image23| image:: img/05.spawning_mobs/23.timeout_signal.png)
|
||||
.. |image24| image:: img/05.spawning_mobs/24.connect_timer_to_main.png)
|
||||
.. |image25| image:: img/05.spawning_mobs/25.spawn_result.png)
|
||||
|
@ -275,12 +275,12 @@ With that, you should be able to kill monsters by jumping on them. You can press
|
||||
|
||||
However, the player won't die yet. We'll work on that in the next part.
|
||||
|
||||
.. |image0| image:: img/06.jump_and_squash/02.project_settings.png
|
||||
.. |image1| image:: img/06.jump_and_squash/03.physics_layers.png
|
||||
.. |image2| image:: img/06.jump_and_squash/04.default_physics_properties.png
|
||||
.. |image3| image:: img/06.jump_and_squash/05.toggle_layer_and_mask.png
|
||||
.. |image4| image:: img/06.jump_and_squash/06.named_checkboxes.png
|
||||
.. |image5| image:: img/06.jump_and_squash/07.player_physics_mask.png
|
||||
.. |image6| image:: img/06.jump_and_squash/08.mob_physics_mask.png
|
||||
.. |image7| image:: img/06.jump_and_squash/09.groups_tab.png
|
||||
.. |image8| image:: img/06.jump_and_squash/10.group_scene_icon.png
|
||||
.. |image0| image:: img/06.jump_and_squash/02.project_settings.png)
|
||||
.. |image1| image:: img/06.jump_and_squash/03.physics_layers.png)
|
||||
.. |image2| image:: img/06.jump_and_squash/04.default_physics_properties.png)
|
||||
.. |image3| image:: img/06.jump_and_squash/05.toggle_layer_and_mask.png)
|
||||
.. |image4| image:: img/06.jump_and_squash/06.named_checkboxes.png)
|
||||
.. |image5| image:: img/06.jump_and_squash/07.player_physics_mask.png)
|
||||
.. |image6| image:: img/06.jump_and_squash/08.mob_physics_mask.png)
|
||||
.. |image7| image:: img/06.jump_and_squash/09.groups_tab.png)
|
||||
.. |image8| image:: img/06.jump_and_squash/10.group_scene_icon.png)
|
||||
|
@ -265,9 +265,9 @@ gdscript GDScript
|
||||
|
||||
See you in the next lesson to add the score and the retry option.
|
||||
|
||||
.. |image0| image:: img/07.killing_player/01.adding_area_node.png
|
||||
.. |image1| image:: img/07.killing_player/02.cylinder_shape.png
|
||||
.. |image2| image:: img/07.killing_player/03.cylinder_in_editor.png
|
||||
.. |image3| image:: img/07.killing_player/04.mob_detector_properties.png
|
||||
.. |image4| image:: img/07.killing_player/05.body_entered_signal.png
|
||||
.. |image5| image:: img/07.killing_player/06.player_hit_signal.png
|
||||
.. |image0| image:: img/07.killing_player/01.adding_area_node.png)
|
||||
.. |image1| image:: img/07.killing_player/02.cylinder_shape.png)
|
||||
.. |image2| image:: img/07.killing_player/03.cylinder_in_editor.png)
|
||||
.. |image3| image:: img/07.killing_player/04.mob_detector_properties.png)
|
||||
.. |image4| image:: img/07.killing_player/05.body_entered_signal.png)
|
||||
.. |image5| image:: img/07.killing_player/06.player_hit_signal.png)
|
||||
|
@ -366,27 +366,27 @@ gdscript GDScript
|
||||
$UserInterface/Retry.show()
|
||||
```
|
||||
|
||||
.. |image0| image:: img/08.score_and_replay/01.label_node.png
|
||||
.. |image1| image:: img/08.score_and_replay/02.score_placeholder.png
|
||||
.. |image2| image:: img/08.score_and_replay/02.score_custom_color.png
|
||||
.. |image3| image:: img/08.score_and_replay/02.score_color_picker.png
|
||||
.. |image4| image:: img/08.score_and_replay/02.score_label_moved.png
|
||||
.. |image5| image:: img/08.score_and_replay/03.creating_theme.png
|
||||
.. |image6| image:: img/08.score_and_replay/04.theme_preview.png
|
||||
.. |image7| image:: img/08.score_and_replay/05.dynamic_font.png
|
||||
.. |image8| image:: img/08.score_and_replay/06.font_data.png
|
||||
.. |image9| image:: img/08.score_and_replay/07.font_size.png
|
||||
.. |image10| image:: img/08.score_and_replay/08.open_main_script.png
|
||||
.. |image11| image:: img/08.score_and_replay/09.score_in_game.png
|
||||
.. |image12| image:: img/08.score_and_replay/10.layout_icon.png
|
||||
.. |image13| image:: img/08.score_and_replay/11.full_rect_option.png
|
||||
.. |image14| image:: img/08.score_and_replay/12.anchors_updated.png
|
||||
.. |image15| image:: img/08.score_and_replay/13.retry_color_picker.png
|
||||
.. |image16| image:: img/08.score_and_replay/14.retry_node.png
|
||||
.. |image17| image:: img/08.score_and_replay/15.layout_center.png
|
||||
.. |image18| image:: img/08.score_and_replay/16.new_scene.png
|
||||
.. |image19| image:: img/08.score_and_replay/17.music_player_node.png
|
||||
.. |image20| image:: img/08.score_and_replay/18.music_node_properties.png
|
||||
.. |image21| image:: img/08.score_and_replay/19.register_autoload.png
|
||||
.. |image22| image:: img/08.score_and_replay/20.scene_dock_tabs.png
|
||||
.. |image23| image:: img/08.score_and_replay/21.remote_scene_tree.png
|
||||
.. |image0| image:: img/08.score_and_replay/01.label_node.png)
|
||||
.. |image1| image:: img/08.score_and_replay/02.score_placeholder.png)
|
||||
.. |image2| image:: img/08.score_and_replay/02.score_custom_color.png)
|
||||
.. |image3| image:: img/08.score_and_replay/02.score_color_picker.png)
|
||||
.. |image4| image:: img/08.score_and_replay/02.score_label_moved.png)
|
||||
.. |image5| image:: img/08.score_and_replay/03.creating_theme.png)
|
||||
.. |image6| image:: img/08.score_and_replay/04.theme_preview.png)
|
||||
.. |image7| image:: img/08.score_and_replay/05.dynamic_font.png)
|
||||
.. |image8| image:: img/08.score_and_replay/06.font_data.png)
|
||||
.. |image9| image:: img/08.score_and_replay/07.font_size.png)
|
||||
.. |image10| image:: img/08.score_and_replay/08.open_main_script.png)
|
||||
.. |image11| image:: img/08.score_and_replay/09.score_in_game.png)
|
||||
.. |image12| image:: img/08.score_and_replay/10.layout_icon.png)
|
||||
.. |image13| image:: img/08.score_and_replay/11.full_rect_option.png)
|
||||
.. |image14| image:: img/08.score_and_replay/12.anchors_updated.png)
|
||||
.. |image15| image:: img/08.score_and_replay/13.retry_color_picker.png)
|
||||
.. |image16| image:: img/08.score_and_replay/14.retry_node.png)
|
||||
.. |image17| image:: img/08.score_and_replay/15.layout_center.png)
|
||||
.. |image18| image:: img/08.score_and_replay/16.new_scene.png)
|
||||
.. |image19| image:: img/08.score_and_replay/17.music_player_node.png)
|
||||
.. |image20| image:: img/08.score_and_replay/18.music_node_properties.png)
|
||||
.. |image21| image:: img/08.score_and_replay/19.register_autoload.png)
|
||||
.. |image22| image:: img/08.score_and_replay/20.scene_dock_tabs.png)
|
||||
.. |image23| image:: img/08.score_and_replay/21.remote_scene_tree.png)
|
||||
|
@ -360,26 +360,26 @@ gdscript GDScript
|
||||
queue_free()
|
||||
```
|
||||
|
||||
.. |image0| image:: img/squash-the-creeps-final.gif
|
||||
.. |image1| image:: img/09.adding_animations/01.animation_player_dock.png
|
||||
.. |image2| image:: img/09.adding_animations/02.new_animation.png
|
||||
.. |image3| image:: img/09.adding_animations/03.float_name.png
|
||||
.. |image4| image:: img/09.adding_animations/03.timeline.png
|
||||
.. |image5| image:: img/09.adding_animations/04.autoplay_and_loop.png
|
||||
.. |image6| image:: img/09.adding_animations/05.pin_icon.png
|
||||
.. |image7| image:: img/09.adding_animations/06.animation_duration.png
|
||||
.. |image8| image:: img/09.adding_animations/07.editable_timeline.png
|
||||
.. |image9| image:: img/09.adding_animations/08.zoom_slider.png
|
||||
.. |image10| image:: img/09.adding_animations/09.creating_first_keyframe.png
|
||||
.. |image11| image:: img/09.adding_animations/10.initial_keys.png
|
||||
.. |image12| image:: img/09.adding_animations/11.moving_keys.png
|
||||
.. |image13| image:: img/09.adding_animations/12.second_keys_values.png
|
||||
.. |image14| image:: img/09.adding_animations/13.second_keys.png
|
||||
.. |image15| image:: img/09.adding_animations/14.play_button.png
|
||||
.. |image16| image:: img/09.adding_animations/15.box_select.png
|
||||
.. |image17| image:: img/09.adding_animations/16.easing_property.png
|
||||
.. |image18| image:: img/09.adding_animations/17.ease_out.png
|
||||
.. |image19| image:: img/09.adding_animations/18.ease_out_second_rotation_key.png
|
||||
.. |image20| image:: img/09.adding_animations/19.ease_in_second_translation_key.png
|
||||
.. |image21| image:: img/09.adding_animations/20.float_animation.gif
|
||||
.. |image22| image:: img/09.adding_animations/21.script_icon.png
|
||||
.. |image0| image:: img/squash-the-creeps-final.gif)
|
||||
.. |image1| image:: img/09.adding_animations/01.animation_player_dock.png)
|
||||
.. |image2| image:: img/09.adding_animations/02.new_animation.png)
|
||||
.. |image3| image:: img/09.adding_animations/03.float_name.png)
|
||||
.. |image4| image:: img/09.adding_animations/03.timeline.png)
|
||||
.. |image5| image:: img/09.adding_animations/04.autoplay_and_loop.png)
|
||||
.. |image6| image:: img/09.adding_animations/05.pin_icon.png)
|
||||
.. |image7| image:: img/09.adding_animations/06.animation_duration.png)
|
||||
.. |image8| image:: img/09.adding_animations/07.editable_timeline.png)
|
||||
.. |image9| image:: img/09.adding_animations/08.zoom_slider.png)
|
||||
.. |image10| image:: img/09.adding_animations/09.creating_first_keyframe.png)
|
||||
.. |image11| image:: img/09.adding_animations/10.initial_keys.png)
|
||||
.. |image12| image:: img/09.adding_animations/11.moving_keys.png)
|
||||
.. |image13| image:: img/09.adding_animations/12.second_keys_values.png)
|
||||
.. |image14| image:: img/09.adding_animations/13.second_keys.png)
|
||||
.. |image15| image:: img/09.adding_animations/14.play_button.png)
|
||||
.. |image16| image:: img/09.adding_animations/15.box_select.png)
|
||||
.. |image17| image:: img/09.adding_animations/16.easing_property.png)
|
||||
.. |image18| image:: img/09.adding_animations/17.ease_out.png)
|
||||
.. |image19| image:: img/09.adding_animations/18.ease_out_second_rotation_key.png)
|
||||
.. |image20| image:: img/09.adding_animations/19.ease_in_second_translation_key.png)
|
||||
.. |image21| image:: img/09.adding_animations/20.float_animation.gif)
|
||||
.. |image22| image:: img/09.adding_animations/21.script_icon.png)
|
||||
|
@ -67,4 +67,4 @@ Contents
|
||||
09.adding_animations
|
||||
going_further
|
||||
|
||||
.. |image0| image:: img/squash-the-creeps-final.gif
|
||||
.. |image0| image:: img/squash-the-creeps-final.gif)
|
||||
|
@ -22,19 +22,19 @@ When you launch Godot, the first window you see is the Project Manager. In the
|
||||
default tab, "Projects," you can manage existing projects, import or create new
|
||||
ones, and more.
|
||||
|
||||
.. image:: img/editor_intro_project_manager.png
|
||||
![](img/editor_intro_project_manager.png)
|
||||
|
||||
At the top of the window, there is another tab named "Asset Library Projects".
|
||||
In the open-source asset library you can search for demo projects, templates,
|
||||
and completed projects, including many that are developed by the community.
|
||||
|
||||
.. image:: img/editor_intro_project_templates.png
|
||||
![](img/editor_intro_project_templates.png)
|
||||
|
||||
You can also change the editor's language using the drop-down menu to the right
|
||||
of the engine's version in the window's top-right corner. By default, it is in
|
||||
English (EN).
|
||||
|
||||
.. image:: img/editor_intro_language.png
|
||||
![](img/editor_intro_language.png)
|
||||
|
||||
First look at Godot's editor
|
||||
----------------------------
|
||||
@ -42,51 +42,51 @@ First look at Godot's editor
|
||||
When you open a new or an existing project, the editor's interface appears.
|
||||
Let's look at its main areas.
|
||||
|
||||
.. image:: img/editor_intro_editor_empty.png
|
||||
![](img/editor_intro_editor_empty.png)
|
||||
|
||||
By default, it features **menus**, **main screens**, and playtest buttons along
|
||||
the window's top edge.
|
||||
|
||||
.. image:: img/editor_intro_top_menus.png
|
||||
![](img/editor_intro_top_menus.png)
|
||||
|
||||
In the center is the **viewport** with its **toolbar** at the top, where you'll
|
||||
find tools to move, scale, or lock the scene's nodes.
|
||||
|
||||
.. image:: img/editor_intro_3d_viewport.png
|
||||
![](img/editor_intro_3d_viewport.png)
|
||||
|
||||
On either side of the viewport sit the **docks**. And at the bottom of the
|
||||
window lies the **bottom panel**.
|
||||
|
||||
The toolbar changes based on the context and selected node. Here is the 2D toolbar.
|
||||
|
||||
.. image:: img/editor_intro_toolbar_2d.png
|
||||
![](img/editor_intro_toolbar_2d.png)
|
||||
|
||||
Below is the 3D one.
|
||||
|
||||
.. image:: img/editor_intro_toolbar_3d.png
|
||||
![](img/editor_intro_toolbar_3d.png)
|
||||
|
||||
Let's look at the docks. The **FileSystem** dock lists your project files, be it
|
||||
scripts, images, audio samples, and more.
|
||||
|
||||
.. image:: img/editor_intro_filesystem_dock.png
|
||||
![](img/editor_intro_filesystem_dock.png)
|
||||
|
||||
The **Scene** dock lists the active scene's nodes.
|
||||
|
||||
.. image:: img/editor_intro_scene_dock.png
|
||||
![](img/editor_intro_scene_dock.png)
|
||||
|
||||
The **Inspector** allows you to edit the properties of a selected node.
|
||||
|
||||
.. image:: img/editor_intro_inspector_dock.png
|
||||
![](img/editor_intro_inspector_dock.png)
|
||||
|
||||
The **bottom panel**, situated below the viewport, is the host for the debug
|
||||
console, the animation editor, the audio mixer, and more. They can take precious
|
||||
space, that's why they're folded by default.
|
||||
|
||||
.. image:: img/editor_intro_bottom_panels.png
|
||||
![](img/editor_intro_bottom_panels.png)
|
||||
|
||||
When you click on one, it expands vertically. Below, you can see the animation editor opened.
|
||||
|
||||
.. image:: img/editor_intro_bottom_panel_animation.png
|
||||
![](img/editor_intro_bottom_panel_animation.png)
|
||||
|
||||
The four main screens
|
||||
---------------------
|
||||
@ -97,17 +97,17 @@ There are four main screen buttons centered at the top of the editor:
|
||||
You'll use the **2D screen** for all types of games. In addition to 2D games,
|
||||
the 2D screen is where you'll build your interfaces.
|
||||
|
||||
.. image:: img/editor_intro_workspace_2d.png
|
||||
![](img/editor_intro_workspace_2d.png)
|
||||
|
||||
In the **3D screen**, you can work with meshes, lights, and design levels for
|
||||
3D games.
|
||||
|
||||
.. image:: img/editor_intro_workspace_3d.png
|
||||
![](img/editor_intro_workspace_3d.png)
|
||||
|
||||
Notice the perspective button under the toolbar. Clicking on it opens a list of
|
||||
options related to the 3D view.
|
||||
|
||||
.. image:: img/editor_intro_3d_viewport_perspective.png
|
||||
![](img/editor_intro_3d_viewport_perspective.png)
|
||||
|
||||
.. note:: Read `doc_introduction_to_3d` for more detail about the **3D
|
||||
main screen**.
|
||||
@ -115,12 +115,12 @@ options related to the 3D view.
|
||||
The **Script screen** is a complete code editor with a debugger, rich
|
||||
auto-completion, and built-in code reference.
|
||||
|
||||
.. image:: img/editor_intro_workspace_script.png
|
||||
![](img/editor_intro_workspace_script.png)
|
||||
|
||||
Finally, the **AssetLib** is a library of free and open-source add-ons, scripts,
|
||||
and assets to use in your projects.
|
||||
|
||||
.. image:: img/editor_intro_workspace_assetlib.png
|
||||
![](img/editor_intro_workspace_assetlib.png)
|
||||
|
||||
.. seealso:: You can learn more about the asset library in
|
||||
`doc_what_is_assetlib`.
|
||||
@ -140,13 +140,13 @@ signal by any one of the following methods:
|
||||
or built-in variable in the script editor.
|
||||
|
||||
|
||||
.. image:: img/editor_intro_search_help_button.png
|
||||
![](img/editor_intro_search_help_button.png)
|
||||
|
||||
When you do any of these, a window pops up. Type to search for any item. You can
|
||||
also use it to browse available objects and methods.
|
||||
|
||||
.. image:: img/editor_intro_search_help.png
|
||||
![](img/editor_intro_search_help.png)
|
||||
|
||||
Double-click on an item to open the corresponding page in the script main screen.
|
||||
|
||||
.. image:: img/editor_intro_help_class_animated_sprite.png
|
||||
![](img/editor_intro_help_class_animated_sprite.png)
|
||||
|
@ -191,9 +191,9 @@ base unit for 2D scenes is pixels.** Even though the engines are
|
||||
separate, you can render 2D in 3D, 3D in 2D, and overlay 2D sprites and
|
||||
interfaces over your 3D world.
|
||||
|
||||
.. |image0| image:: img/engine_design_01.png
|
||||
.. |image1| image:: img/engine_design_02.png
|
||||
.. |image2| image:: img/engine_design_03.png
|
||||
.. |image3| image:: img/engine_design_visual_script.png
|
||||
.. |image4| image:: img/engine_design_fsm_plugin.png
|
||||
.. |image5| image:: img/engine_design_rpg_in_a_box.png
|
||||
.. |image0| image:: img/engine_design_01.png)
|
||||
.. |image1| image:: img/engine_design_02.png)
|
||||
.. |image2| image:: img/engine_design_03.png)
|
||||
.. |image3| image:: img/engine_design_visual_script.png)
|
||||
.. |image4| image:: img/engine_design_fsm_plugin.png)
|
||||
.. |image5| image:: img/engine_design_rpg_in_a_box.png)
|
||||
|
@ -35,14 +35,14 @@ tremendously since its open-source release in 2014.
|
||||
|
||||
Some examples of games created with Godot include Ex-Zodiac and Helms of Fury.
|
||||
|
||||
.. image:: img/introduction_ex_zodiac.png
|
||||
![](img/introduction_ex_zodiac.png)
|
||||
|
||||
.. image:: img/introduction_helms_of_fury.jpg
|
||||
![](img/introduction_helms_of_fury.jpg
|
||||
|
||||
As for applications, the open-source pixel art drawing program Pixelorama is
|
||||
powered by Godot, and so is the voxel RPG creator RPG in a box.
|
||||
|
||||
.. image:: img/introduction_rpg_in_a_box.png
|
||||
![](img/introduction_rpg_in_a_box.png)
|
||||
|
||||
You can find many more examples in the `official showcase videos`_.
|
||||
|
||||
@ -53,7 +53,7 @@ Godot comes with a fully-fledged game editor with integrated tools to answer the
|
||||
most common needs. It includes a code editor, an animation editor, a tilemap
|
||||
editor, a shader editor, a debugger, a profiler, and more.
|
||||
|
||||
.. image:: img/introduction_editor.png
|
||||
![](img/introduction_editor.png)
|
||||
|
||||
The team strives to offer a feature-rich game editor with a consistent user
|
||||
experience. While there is always room for improvement, the user interface keeps
|
||||
@ -64,7 +64,7 @@ support importing 3D scenes designed in Blender_ and maintain plugins to code in
|
||||
VSCode_ and Emacs_ for GDScript and C#. We also support Visual Studio for C# on
|
||||
Windows.
|
||||
|
||||
.. image:: img/introduction_vscode.png
|
||||
![](img/introduction_vscode.png)
|
||||
|
||||
Programming languages
|
||||
---------------------
|
||||
|
@ -24,12 +24,12 @@ a weapon, a menu in the user interface, a single house, an entire level, or
|
||||
anything you can think of. Godot's scenes are flexible; they fill the role of
|
||||
both prefabs and scenes in some other game engines.
|
||||
|
||||
.. image:: img/key_concepts_main_menu.png
|
||||
![](img/key_concepts_main_menu.png)
|
||||
|
||||
You can also nest scenes. For example, you can put your character in a level,
|
||||
and drag and drop a scene as a child of it.
|
||||
|
||||
.. image:: img/key_concepts_scene_example.png
|
||||
![](img/key_concepts_scene_example.png)
|
||||
|
||||
Nodes
|
||||
-----
|
||||
@ -38,7 +38,7 @@ A scene is composed of one or more **nodes**. Nodes are your game's smallest
|
||||
building blocks that you arrange into trees. Here's an example of a character's
|
||||
nodes.
|
||||
|
||||
.. image:: img/key_concepts_character_nodes.png
|
||||
![](img/key_concepts_character_nodes.png)
|
||||
|
||||
It is made of a `KinematicBody2D` node named "Character", a `Sprite`, a
|
||||
`Camera2D`, and a `CollisionShape2D`.
|
||||
@ -54,7 +54,7 @@ Godot provides an extensive library of base node types you can combine and
|
||||
extend to build more powerful ones. 2D, 3D, or user interface, you will do most
|
||||
things with these nodes.
|
||||
|
||||
.. image:: img/key_concepts_node_menu.png
|
||||
![](img/key_concepts_node_menu.png)
|
||||
|
||||
The scene tree
|
||||
--------------
|
||||
@ -64,7 +64,7 @@ scenes. And as scenes are trees of nodes, the scene tree also is a tree of
|
||||
nodes. But it's easier to think of your game in terms of scenes as they can
|
||||
represent characters, weapons, doors, or your user interface.
|
||||
|
||||
.. image:: img/key_concepts_scene_tree.png
|
||||
![](img/key_concepts_scene_tree.png)
|
||||
|
||||
Signals
|
||||
-------
|
||||
@ -73,7 +73,7 @@ Nodes emit signals when some event occurs. This feature allows you to make
|
||||
nodes communicate without hard-wiring them in code. It gives you a lot of
|
||||
flexibility in how you structure your scenes.
|
||||
|
||||
.. image:: img/key_concepts_signals.png
|
||||
![](img/key_concepts_signals.png)
|
||||
|
||||
.. note:: Signals are Godot's version of the *observer* pattern. You can read
|
||||
more about it here:
|
||||
|
@ -21,7 +21,7 @@ explore broad topics while the search bar will help you find more specific
|
||||
pages. If a page exists for a given theme, it will often link to more related
|
||||
content.
|
||||
|
||||
.. image:: img/manual_search.png
|
||||
![](img/manual_search.png)
|
||||
|
||||
The manual has a companion class reference that explains each Godot class's
|
||||
available functions and properties when programming. While the manual covers
|
||||
@ -31,7 +31,7 @@ access it both online and offline. We recommend browsing the reference offline,
|
||||
from within the Godot editor. To do so, go to Help -> Search or press
|
||||
:kbd:`F1`.
|
||||
|
||||
.. image:: img/manual_class_reference_search.png
|
||||
![](img/manual_class_reference_search.png)
|
||||
|
||||
To browse it online, head to the manual's `Class Reference <toc-class-ref>`
|
||||
section.
|
||||
@ -42,7 +42,7 @@ A class reference's page tells you:
|
||||
links to jump to parent classes and see the properties and methods a type
|
||||
inherits.
|
||||
|
||||
.. image:: img/manual_class_reference_inheritance.png
|
||||
![](img/manual_class_reference_inheritance.png)
|
||||
|
||||
2. A summary of the class's role and use cases.
|
||||
|
||||
@ -116,7 +116,7 @@ information:
|
||||
the code you write affects nodes in your scenes. As a result, you should
|
||||
think of those scenes as part of your source code.
|
||||
|
||||
.. image:: img/key_concepts_scene_tree.png
|
||||
![](img/key_concepts_scene_tree.png)
|
||||
|
||||
Also, please don't take a picture with your phone, the low quality and screen
|
||||
reflections can make it hard to understand the image. Your operating system
|
||||
|
@ -18,13 +18,13 @@ Here's an example of a ball. It's composed of a `RigidBody2D
|
||||
and bounce on walls, a `Sprite` node, and a
|
||||
`CollisionShape2D`.
|
||||
|
||||
.. image:: img/instancing_ball_scene.png
|
||||
![](img/instancing_ball_scene.png)
|
||||
|
||||
Once you saved a scene, it works as a blueprint: you can reproduce it in other
|
||||
scenes as many times as you'd like. Replicating an object from a template like
|
||||
this is called **instancing**.
|
||||
|
||||
.. image:: img/instancing_ball_instances_example.png
|
||||
![](img/instancing_ball_instances_example.png)
|
||||
|
||||
As we mentioned in the previous part, instanced scenes behave like a node: the
|
||||
editor hides their content by default. When you instance the Ball, you only see
|
||||
@ -45,44 +45,44 @@ you to download the ball's sample project we prepared for you:
|
||||
Extract the archive on your computer. Then, open Godot, and in the project
|
||||
manager, click the Import button to import the project.
|
||||
|
||||
.. image:: img/instancing_import_button.png
|
||||
![](img/instancing_import_button.png)
|
||||
|
||||
In the pop-up that appears, click the browse button and navigate to the folder
|
||||
you extracted.
|
||||
|
||||
.. image:: img/instancing_import_browse.png
|
||||
![](img/instancing_import_browse.png)
|
||||
|
||||
Double-click the `project.godot` file to open it.
|
||||
|
||||
.. image:: img/instancing_import_project_file.png
|
||||
![](img/instancing_import_project_file.png)
|
||||
|
||||
Finally, click the Import & Edit button.
|
||||
|
||||
.. image:: img/instancing_import_and_edit_button.png
|
||||
![](img/instancing_import_and_edit_button.png)
|
||||
|
||||
The project contains two packed scenes: `Main.tscn`, containing walls against
|
||||
which the ball collides, and `Ball.tscn`. The Main scene should open
|
||||
automatically.
|
||||
|
||||
.. image:: img/instancing_main_scene.png
|
||||
![](img/instancing_main_scene.png)
|
||||
|
||||
Let's add a ball as a child of the Main node. In the Scene dock, select the Main
|
||||
node. Then, click the link icon at the top of the scene dock. This button allows
|
||||
you to add an instance of a scene as a child of the currently selected node.
|
||||
|
||||
.. image:: img/instancing_scene_link_button.png
|
||||
![](img/instancing_scene_link_button.png)
|
||||
|
||||
Double-click the ball scene to instance it.
|
||||
|
||||
.. image:: img/instancing_instance_child_window.png
|
||||
![](img/instancing_instance_child_window.png)
|
||||
|
||||
The ball appears in the top-left corner of the viewport.
|
||||
|
||||
.. image:: img/instancing_ball_instanced.png
|
||||
![](img/instancing_ball_instanced.png)
|
||||
|
||||
Click on it and drag it towards the center of the view.
|
||||
|
||||
.. image:: img/instancing_ball_moved.png
|
||||
![](img/instancing_ball_moved.png)
|
||||
|
||||
Play the game by pressing F5. You should see it fall.
|
||||
|
||||
@ -90,11 +90,11 @@ Now, we want to create more instances of the Ball node. With the ball still
|
||||
selected, press :kbd:`Ctrl-D` (:kbd:`Cmd-D` on macOS) to call the duplicate
|
||||
command. Click and drag to move the new ball to a different location.
|
||||
|
||||
.. image:: img/instancing_ball_duplicated.png
|
||||
![](img/instancing_ball_duplicated.png)
|
||||
|
||||
You can repeat this process until you have several in the scene.
|
||||
|
||||
.. image:: img/instancing_main_scene_with_balls.png
|
||||
![](img/instancing_main_scene_with_balls.png)
|
||||
|
||||
Play the game again. You should now see every ball fall independently from one
|
||||
another. This is what instances do. Each is an independent reproduction of a
|
||||
@ -117,12 +117,12 @@ There is more to instances. With this feature, you can:
|
||||
Let's try this. Open `Ball.tscn` and select the Ball node. In the Inspector on
|
||||
the right, click on the PhysicsMaterial property to expand it.
|
||||
|
||||
.. image:: img/instancing_physics_material_expand.png
|
||||
![](img/instancing_physics_material_expand.png)
|
||||
|
||||
Set its Bounce property to `2` by clicking on the number field, typing `2`,
|
||||
and pressing :kbd:`Enter`.
|
||||
|
||||
.. image:: img/instancing_property_bounce_updated.png
|
||||
![](img/instancing_property_bounce_updated.png)
|
||||
|
||||
Play the game by pressing :kbd:`F5` and notice how all balls now bounce a lot
|
||||
more. As the Ball scene is a template for all instances, modifying it and saving
|
||||
@ -131,16 +131,16 @@ causes all instances to update accordingly.
|
||||
Let's now adjust an individual instance. Head back to the Main scene by clicking
|
||||
on the corresponding tab above the viewport.
|
||||
|
||||
.. image:: img/instancing_scene_tabs.png
|
||||
![](img/instancing_scene_tabs.png)
|
||||
|
||||
Select one of the instanced Ball nodes and, in the Inspector, set its Gravity
|
||||
Scale value to `10`.
|
||||
|
||||
.. image:: img/instancing_property_gravity_scale.png
|
||||
![](img/instancing_property_gravity_scale.png)
|
||||
|
||||
A grey "revert" button appears next to the adjusted property.
|
||||
|
||||
.. image:: img/instancing_property_revert_icon.png
|
||||
![](img/instancing_property_revert_icon.png)
|
||||
|
||||
This icon indicates you are overriding a value from the source packed scene.
|
||||
Even if you modify the property in the original scene, the value override will
|
||||
@ -172,7 +172,7 @@ and structure your code around them.
|
||||
|
||||
For example, you could break down a shooter game like so:
|
||||
|
||||
.. image:: img/instancing_diagram_shooter.png
|
||||
![](img/instancing_diagram_shooter.png)
|
||||
|
||||
You can come up with a diagram like this for almost any type of game. Each
|
||||
rectangle represents an entity that's visible in the game from the player's
|
||||
@ -191,7 +191,7 @@ scene instantiation means you need little other architectural code.
|
||||
Here's the example of a scene diagram for an open-world game with tons of assets
|
||||
and nested elements:
|
||||
|
||||
.. image:: img/instancing_diagram_open_world.png
|
||||
![](img/instancing_diagram_open_world.png)
|
||||
|
||||
Imagine we started by creating the room. We could make a couple of different
|
||||
room scenes, with unique arrangements of furniture in them. Later, we could make
|
||||
|
@ -16,7 +16,7 @@ Nodes
|
||||
ingredients in a recipe. There are dozens of kinds that can display an image,
|
||||
play a sound, represent a camera, and much more.
|
||||
|
||||
.. image:: img/nodes_and_scenes_nodes.png
|
||||
![](img/nodes_and_scenes_nodes.png)
|
||||
|
||||
All nodes have the following attributes:
|
||||
|
||||
@ -32,7 +32,7 @@ combining them produces more complex behavior. As we saw before, you can build a
|
||||
playable character the camera follows using a kinematic body node named
|
||||
"Character", a sprite node, a camera node, and a collision shape node.
|
||||
|
||||
.. image:: img/nodes_and_scenes_character_nodes.png
|
||||
![](img/nodes_and_scenes_character_nodes.png)
|
||||
|
||||
Scenes
|
||||
------
|
||||
@ -46,7 +46,7 @@ Scenes allow you to structure your game's code however you want. You can
|
||||
**compose nodes** to create custom and complex node types, like a game character
|
||||
that runs and jumps, a life bar, a chest with which you can interact, and more.
|
||||
|
||||
.. image:: img/nodes_and_scenes_3d_scene_example.png
|
||||
![](img/nodes_and_scenes_3d_scene_example.png)
|
||||
|
||||
The Godot editor essentially is a **scene editor**. It has plenty of tools for
|
||||
editing 2D and 3D scenes, as well as user interfaces. A Godot project can
|
||||
@ -68,7 +68,7 @@ Let's create our first scene with a single node. To do so, you will need to
|
||||
create a new project first. After opening the project, you should see an empty
|
||||
editor.
|
||||
|
||||
.. image:: img/nodes_and_scenes_01_empty_editor.png
|
||||
![](img/nodes_and_scenes_01_empty_editor.png)
|
||||
|
||||
In an empty scene, the Scene dock on the left shows several options to add a
|
||||
root node quickly. "2D Scene" adds a Node2D node, "3D Scene" adds a Spatial
|
||||
@ -83,20 +83,20 @@ text on the screen.
|
||||
|
||||
Press the "Add Child Node" button or "Other Node" to create a root node.
|
||||
|
||||
.. image:: img/nodes_and_scenes_02_scene_dock.png
|
||||
![](img/nodes_and_scenes_02_scene_dock.png)
|
||||
|
||||
The Create Node dialog opens, showing the long list of available nodes.
|
||||
|
||||
.. image:: img/nodes_and_scenes_03_create_node_window.png
|
||||
![](img/nodes_and_scenes_03_create_node_window.png)
|
||||
|
||||
Select the Label node. You can type its name to filter down the list.
|
||||
|
||||
.. image:: img/nodes_and_scenes_04_create_label_window.png
|
||||
![](img/nodes_and_scenes_04_create_label_window.png)
|
||||
|
||||
Click on the Label node to select it and click the Create button at the bottom
|
||||
of the window.
|
||||
|
||||
.. image:: img/nodes_and_scenes_05_editor_with_label.png
|
||||
![](img/nodes_and_scenes_05_editor_with_label.png)
|
||||
|
||||
A lot happens when you add a scene's first node. The scene changes to the 2D
|
||||
workspace because Label is a 2D node type. The Label appears, selected, in the
|
||||
@ -112,19 +112,19 @@ The next step is to change the Label's "Text" property. Let's change it to
|
||||
Head to the Inspector dock on the right of the viewport. Click inside the field
|
||||
below the Text property and type "Hello World".
|
||||
|
||||
.. image:: img/nodes_and_scenes_06_label_text.png
|
||||
![](img/nodes_and_scenes_06_label_text.png)
|
||||
|
||||
You will see the text draw in the viewport as you type.
|
||||
|
||||
You can move your Label node in the viewport by selecting the move tool in the
|
||||
toolbar.
|
||||
|
||||
.. image:: img/nodes_and_scenes_07_move_tool.png
|
||||
![](img/nodes_and_scenes_07_move_tool.png)
|
||||
|
||||
With the Label selected, click and drag anywhere in the viewport to
|
||||
move it to the center of the view delimited by the rectangle.
|
||||
|
||||
.. image:: img/nodes_and_scenes_08_hello_world_text.png
|
||||
![](img/nodes_and_scenes_08_hello_world_text.png)
|
||||
|
||||
Running the scene
|
||||
-----------------
|
||||
@ -132,16 +132,16 @@ Running the scene
|
||||
Everything's ready to run the scene! Press the Play Scene button in the
|
||||
top-right of the screen or press :kbd:`F6` (:kbd:`Cmd + R` on macOS).
|
||||
|
||||
.. image:: img/nodes_and_scenes_09_play_scene_button.png
|
||||
![](img/nodes_and_scenes_09_play_scene_button.png)
|
||||
|
||||
A popup invites you to save the scene, which is required to run it.
|
||||
|
||||
.. image:: img/nodes_and_scenes_10_save_scene_popup.png
|
||||
![](img/nodes_and_scenes_10_save_scene_popup.png)
|
||||
|
||||
Click the Yes button, and in the file browser that appears, press the Save
|
||||
button to save it as "Label.tscn".
|
||||
|
||||
.. image:: img/nodes_and_scenes_11_save_scene_as.png
|
||||
![](img/nodes_and_scenes_11_save_scene_as.png)
|
||||
|
||||
.. note:: The Save Scene As dialog, like other file dialogs in the editor, only
|
||||
allows you to save files inside the project. The `res://` path at
|
||||
@ -151,7 +151,7 @@ button to save it as "Label.tscn".
|
||||
|
||||
The application should open in a new window and display the text "Hello World".
|
||||
|
||||
.. image:: img/nodes_and_scenes_12_final_result.png
|
||||
![](img/nodes_and_scenes_12_final_result.png)
|
||||
|
||||
Close the window or press :kbd:`F8` to quit the running scene.
|
||||
|
||||
@ -168,16 +168,16 @@ To run our test scene, we used the Play Scene button. Another button next to it
|
||||
allows you to set and run the project's main scene. You can press :kbd:`F5`
|
||||
(:kbd:`Cmd + B` on macOS) to do so.
|
||||
|
||||
.. image:: img/nodes_and_scenes_13_play_button.png
|
||||
![](img/nodes_and_scenes_13_play_button.png)
|
||||
|
||||
A popup window appears and invites you to select the main scene.
|
||||
|
||||
.. image:: img/nodes_and_scenes_14_main_scene_popup.png
|
||||
![](img/nodes_and_scenes_14_main_scene_popup.png)
|
||||
|
||||
Click the Select button, and in the file dialog that appears, double click on
|
||||
Label.tscn.
|
||||
|
||||
.. image:: img/nodes_and_scenes_15_select_main_scene.png
|
||||
![](img/nodes_and_scenes_15_select_main_scene.png)
|
||||
|
||||
The demo should run again. Moving forward, every time you run the project, Godot
|
||||
will use this scene as a starting point.
|
||||
|
@ -23,7 +23,7 @@ circles using GDScript. As we mentioned `in the introduction
|
||||
<toc-learn-introduction>`, we assume you have programming foundations.
|
||||
The equivalent C# code has been included in another tab for convenience.
|
||||
|
||||
.. image:: img/scripting_first_script_rotating_godot.gif
|
||||
![](img/scripting_first_script_rotating_godot.gif)
|
||||
|
||||
.. seealso:: To learn more about GDScript, its keywords, and its syntax, head to
|
||||
the `GDScript reference<doc_gdscript>`.
|
||||
@ -42,33 +42,33 @@ community.
|
||||
We need to create a Sprite node to display it in the game. In the Scene dock,
|
||||
click the Other Node button.
|
||||
|
||||
.. image:: img/scripting_first_script_click_other_node.png
|
||||
![](img/scripting_first_script_click_other_node.png)
|
||||
|
||||
Type "Sprite" in the search bar to filter nodes and double-click on Sprite to
|
||||
create the node.
|
||||
|
||||
.. image:: img/scripting_first_script_add_sprite_node.png
|
||||
![](img/scripting_first_script_add_sprite_node.png)
|
||||
|
||||
Your Scene tab should now only have a Sprite node.
|
||||
|
||||
.. image:: img/scripting_first_script_scene_tree.png
|
||||
![](img/scripting_first_script_scene_tree.png)
|
||||
|
||||
A Sprite node needs a texture to display. In the Inspector on the right, you can
|
||||
see that the Texture property says "[empty]". To display the Godot icon, click
|
||||
and drag the file `icon.png` from the FileSystem dock onto the Texture slot.
|
||||
and drag the file `icon.png)` from the FileSystem dock onto the Texture slot.
|
||||
|
||||
.. image:: img/scripting_first_script_setting_texture.png
|
||||
![](img/scripting_first_script_setting_texture.png)
|
||||
|
||||
.. note::
|
||||
|
||||
You can create Sprite nodes automatically by dragging and dropping images on
|
||||
the viewport.
|
||||
|
||||
.. image:: img/scripting_first_script_dragging_sprite.png
|
||||
![](img/scripting_first_script_dragging_sprite.png)
|
||||
|
||||
Then, click and drag the icon in the viewport to center it in the game view.
|
||||
|
||||
.. image:: img/scripting_first_script_centering_sprite.png
|
||||
![](img/scripting_first_script_centering_sprite.png)
|
||||
|
||||
Creating a new script
|
||||
---------------------
|
||||
@ -76,7 +76,7 @@ Creating a new script
|
||||
To create and attach a new script to our node, right-click on Sprite in the
|
||||
scene dock and select "Attach Script".
|
||||
|
||||
.. image:: img/scripting_first_script_attach_script.png
|
||||
![](img/scripting_first_script_attach_script.png)
|
||||
|
||||
The Attach Node Script window appears. It allows you to select the script's
|
||||
language and file path, among other options.
|
||||
@ -84,7 +84,7 @@ language and file path, among other options.
|
||||
Change the Template from Default to Empty to start with a clean file. Leave the
|
||||
other options by default and click the Create button to create the script.
|
||||
|
||||
.. image:: img/scripting_first_script_attach_node_script.png
|
||||
![](img/scripting_first_script_attach_node_script.png)
|
||||
|
||||
The Script workspace should appear with your new `Sprite.gd` file open and the
|
||||
following line of code:
|
||||
@ -147,7 +147,7 @@ Save the scene if you haven't already, then press :kbd:`F6` (:kbd:`Cmd + R` on m
|
||||
to run it. Look at the **Output** bottom panel that expands.
|
||||
It should display "Hello, world!".
|
||||
|
||||
.. image:: img/scripting_first_script_print_hello_world.png
|
||||
![](img/scripting_first_script_print_hello_world.png)
|
||||
|
||||
Delete the `_init()` function, so you're only left with the line `extends
|
||||
Sprite`.
|
||||
@ -224,7 +224,7 @@ our node and works with radians.
|
||||
|
||||
Run the scene to see the Godot icon turn in-place.
|
||||
|
||||
.. image:: img/scripting_first_script_godot_turning_in_place.gif
|
||||
![](img/scripting_first_script_godot_turning_in_place.gif)
|
||||
|
||||
Moving forward
|
||||
~~~~~~~~~~~~~~
|
||||
@ -258,7 +258,7 @@ representing a 2D vector.
|
||||
|
||||
Run the scene to see the Godot head run in circles.
|
||||
|
||||
.. image:: img/scripting_first_script_rotating_godot.gif
|
||||
![](img/scripting_first_script_rotating_godot.gif)
|
||||
|
||||
.. note:: Moving a node like that does not take into account colliding with
|
||||
walls or the floor. In `doc_your_first_2d_game`, you will learn
|
||||
|
@ -18,7 +18,7 @@ follows its parent by default. Imagine you want the camera to shake when the pla
|
||||
takes damage. As this feature is not built into Godot, you would attach a script
|
||||
to the Camera2D node and code the shake.
|
||||
|
||||
.. image:: img/scripting_camera_shake.gif
|
||||
![](img/scripting_camera_shake.gif)
|
||||
|
||||
Available scripting languages
|
||||
-----------------------------
|
||||
@ -55,7 +55,7 @@ language specifically for Godot and the needs of game developers. It has a
|
||||
lightweight and straightforward syntax and provides the tightest integration
|
||||
with Godot.
|
||||
|
||||
.. image:: img/scripting_gdscript.png
|
||||
![](img/scripting_gdscript.png)
|
||||
|
||||
For C#, you will need an external code editor like
|
||||
`VSCode <https://code.visualstudio.com/>`_ or Visual Studio. While C# support is
|
||||
@ -116,7 +116,7 @@ amongst game developers, we officially support it. C# is a mature and flexible
|
||||
language with tons of libraries written for it. We could add support for it
|
||||
thanks to a generous donation from Microsoft.
|
||||
|
||||
.. image:: img/scripting_csharp.png
|
||||
![](img/scripting_csharp.png)
|
||||
|
||||
C# offers a good tradeoff between performance and ease of use, although you
|
||||
should be aware of its garbage collector.
|
||||
@ -153,7 +153,7 @@ VisualScript
|
||||
programming language where you connect blocks. It can be a great tool for
|
||||
non-programmers like game designers and artists.
|
||||
|
||||
.. image:: img/scripting_visualscript.png
|
||||
![](img/scripting_visualscript.png)
|
||||
|
||||
You can use other languages to create custom blocks that are specific to your
|
||||
game, for example, to script AIs, quests, or dialogues. That's where the
|
||||
@ -174,7 +174,7 @@ C and C++ via GDNative
|
||||
GDNative allows you to write game code in C or C++ without needing to recompile
|
||||
or even restart Godot.
|
||||
|
||||
.. image:: img/scripting_cpp.png
|
||||
![](img/scripting_cpp.png)
|
||||
|
||||
You can use any version of the language or mix compiler brands and versions for
|
||||
the generated shared libraries, thanks to our use of an internal C API Bridge.
|
||||
|
@ -11,7 +11,7 @@ Building upon the previous lesson `doc_scripting_first_script`, let's look
|
||||
at another important feature of any game: giving control to the player.
|
||||
To add this, we need to modify our `Sprite.gd` code.
|
||||
|
||||
.. image:: img/scripting_first_script_moving_with_input.gif
|
||||
![](img/scripting_first_script_moving_with_input.gif)
|
||||
|
||||
You have two main tools to process the player's input in Godot:
|
||||
|
||||
@ -122,7 +122,7 @@ gdscript GDScript
|
||||
If you run the scene, you should now be able to rotate with the left and right
|
||||
arrow keys and move forward by pressing :kbd:`Up`.
|
||||
|
||||
.. image:: img/scripting_first_script_moving_with_input.gif
|
||||
![](img/scripting_first_script_moving_with_input.gif)
|
||||
|
||||
Summary
|
||||
-------
|
||||
|
@ -43,46 +43,46 @@ lessons.
|
||||
|
||||
Create a new scene by going to the menu Scene -> New Scene.
|
||||
|
||||
.. image:: img/signals_01_new_scene.png
|
||||
![](img/signals_01_new_scene.png)
|
||||
|
||||
In the Scene dock, click the 2D Scene button. This will add a Node2D as our
|
||||
root.
|
||||
|
||||
.. image:: img/signals_02_2d_scene.png
|
||||
![](img/signals_02_2d_scene.png)
|
||||
|
||||
In the FileSystem dock, click and drag the `Sprite.tscn` file you saved
|
||||
previously onto the Node2D to instantiate it.
|
||||
|
||||
.. image:: img/signals_03_dragging_scene.png
|
||||
![](img/signals_03_dragging_scene.png)
|
||||
|
||||
We want to add another node as a sibling of the Sprite. To do so, right-click on
|
||||
Node2D and select Add Child Node.
|
||||
|
||||
.. image:: img/signals_04_add_child_node.png
|
||||
![](img/signals_04_add_child_node.png)
|
||||
|
||||
Search for the Button node type and add it.
|
||||
|
||||
.. image:: img/signals_05_add_button.png
|
||||
![](img/signals_05_add_button.png)
|
||||
|
||||
The node is small by default. Click and drag on the bottom-right handle of the
|
||||
Button in the viewport to resize it.
|
||||
|
||||
.. image:: img/signals_06_drag_button.png
|
||||
![](img/signals_06_drag_button.png)
|
||||
|
||||
If you don't see the handles, ensure the select tool is active in the toolbar.
|
||||
|
||||
.. image:: img/signals_07_select_tool.png
|
||||
![](img/signals_07_select_tool.png)
|
||||
|
||||
Click and drag on the button itself to move it closer to the sprite.
|
||||
|
||||
You can also write a label on the Button by editing its Text property in the
|
||||
Inspector. Enter "Toggle motion".
|
||||
|
||||
.. image:: img/signals_08_toggle_motion_text.png
|
||||
![](img/signals_08_toggle_motion_text.png)
|
||||
|
||||
Your scene tree and viewport should look like this.
|
||||
|
||||
.. image:: img/signals_09_scene_setup.png
|
||||
![](img/signals_09_scene_setup.png)
|
||||
|
||||
Save your newly created scene. You can then run it with :kbd:`F6`.
|
||||
At the moment, the button will be visible, but nothing will happen if you
|
||||
@ -98,15 +98,15 @@ have a script attached to the Sprite node, which we do from the previous lesson.
|
||||
You can connect signals in the Node dock. Select the Button node and, on the
|
||||
right side of the editor, click on the tab named "Node" next to the Inspector.
|
||||
|
||||
.. image:: img/signals_10_node_dock.png
|
||||
![](img/signals_10_node_dock.png)
|
||||
|
||||
The dock displays a list of signals available on the selected node.
|
||||
|
||||
.. image:: img/signals_11_pressed_signals.png
|
||||
![](img/signals_11_pressed_signals.png)
|
||||
|
||||
Double-click the "pressed" signal to open the node connection window.
|
||||
|
||||
.. image:: img/signals_12_node_connection.png
|
||||
![](img/signals_12_node_connection.png)
|
||||
|
||||
There, you can connect the signal to the Sprite node. The node needs a receiver
|
||||
method, a function that Godot will call when the Button emits the signal. The
|
||||
@ -119,7 +119,7 @@ editor generates one for you. By convention, we name these callback methods
|
||||
modes. The simple one only allows you to connect to nodes that have a
|
||||
script attached to them and creates a new callback function on them.
|
||||
|
||||
.. image:: img/signals_advanced_connection_window.png
|
||||
![](img/signals_advanced_connection_window.png)
|
||||
|
||||
The advanced view lets you connect to any node and any built-in
|
||||
function, add arguments to the callback, and set options. You can
|
||||
@ -130,12 +130,12 @@ Click the Connect button to complete the signal connection and jump to the
|
||||
Script workspace. You should see the new method with a connection icon in the
|
||||
left margin.
|
||||
|
||||
.. image:: img/signals_13_signals_connection_icon.png
|
||||
![](img/signals_13_signals_connection_icon.png)
|
||||
|
||||
If you click the icon, a window pops up and displays information about the
|
||||
connection. This feature is only available when connecting nodes in the editor.
|
||||
|
||||
.. image:: img/signals_14_signals_connection_info.png
|
||||
![](img/signals_14_signals_connection_info.png)
|
||||
|
||||
Let's replace the line with the `pass` keyword with code that'll toggle the
|
||||
node's motion.
|
||||
@ -208,16 +208,16 @@ In the Scene dock, right-click on the Sprite node and add a new child node.
|
||||
Search for Timer and add the corresponding node. Your scene should now look like
|
||||
this.
|
||||
|
||||
.. image:: img/signals_15_scene_tree.png
|
||||
![](img/signals_15_scene_tree.png)
|
||||
|
||||
With the Timer node selected, go to the Inspector and check the **Autostart**
|
||||
property.
|
||||
|
||||
.. image:: img/signals_18_timer_autostart.png
|
||||
![](img/signals_18_timer_autostart.png)
|
||||
|
||||
Click the script icon next to Sprite to jump back to the scripting workspace.
|
||||
|
||||
.. image:: img/signals_16_click_script.png
|
||||
![](img/signals_16_click_script.png)
|
||||
|
||||
We need to do two operations to connect the nodes via code:
|
||||
|
||||
@ -339,7 +339,7 @@ gdscript GDScript
|
||||
Your signals work the same way as built-in ones: they appear in the Node tab and
|
||||
you can connect to them like any other.
|
||||
|
||||
.. image:: img/signals_17_custom_signal.png
|
||||
![](img/signals_17_custom_signal.png)
|
||||
|
||||
To emit a signal in your scripts, call `emit_signal()`.
|
||||
|
||||
|
@ -11,7 +11,7 @@ This tutorial explains how the 2D lighting works in the
|
||||
It begins with a brief description of the resources used in the final demo and then describes how
|
||||
to make a scene like the demo step by step.
|
||||
|
||||
.. image:: img/light_shadow_main.png
|
||||
![](img/light_shadow_main.png)
|
||||
|
||||
All the resources for this tutorial can be found in the `official demo repository <https://github.com/godotengine/godot-demo-projects>`_
|
||||
on GitHub. I suggest you download it before starting. Alternatively,
|
||||
@ -25,19 +25,19 @@ For this demo we use four textures: two for the lights, one for the shadow caste
|
||||
and one for the background. I've included links to them all here if you want to download them
|
||||
separately from the demo.
|
||||
|
||||
The first is the background image (`background.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/background.png>`_)
|
||||
The first is the background image (`background.png) <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/background.png)>`_)
|
||||
used in the demo. You do not necessarily need a background, but we use one for the demo.
|
||||
|
||||
The second is a plain black image (`caster.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/caster.png>`_)
|
||||
The second is a plain black image (`caster.png) <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/caster.png)>`_)
|
||||
to use as our shadow caster object. For a top down game this could be a wall or any
|
||||
other object that casts a shadow.
|
||||
|
||||
Next is the light itself (`light.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/light.png>`_).
|
||||
Next is the light itself (`light.png) <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/light.png)>`_).
|
||||
If you click the link you will notice how large it is. The image you use
|
||||
for a light should cover the area you want your light to cover. This image is
|
||||
1024x1024 pixels, so you should use it to cover 1024x1024 pixels in your game.
|
||||
|
||||
Lastly, we have the spotlight image (`spot.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/spot.png>`_).
|
||||
Lastly, we have the spotlight image (`spot.png) <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/spot.png)>`_).
|
||||
The demo uses a blob to show where the light is and the larger light
|
||||
image to show the effect of the light upon the rest of the scene.
|
||||
|
||||
@ -70,7 +70,7 @@ Lights
|
||||
`Lights` cover the entire extent of their respective Texture. They use additive
|
||||
blending to add the color of their texture to the scene.
|
||||
|
||||
.. image:: img/light_shadow_light.png
|
||||
![](img/light_shadow_light.png)
|
||||
|
||||
`Lights` have four `Modes`: `Add`, `Sub`, `Mix`, and `Mask`.
|
||||
|
||||
@ -89,7 +89,7 @@ is the effect of the light), and a `Sprite` blob which is an image showing the
|
||||
location of the light source. A child `Sprite` is not necessary to make a
|
||||
`Light` work.
|
||||
|
||||
.. image:: img/light_shadow_light_blob.png
|
||||
![](img/light_shadow_light_blob.png)
|
||||
|
||||
Shadows
|
||||
-------
|
||||
@ -113,13 +113,13 @@ the process of making a scene like the one found in the demo.
|
||||
First add a `Sprite`_. For your game this can be any
|
||||
background you choose. For this style of shadow it is most likely to be a floor texture.
|
||||
|
||||
.. image:: img/light_shadow_background.png
|
||||
![](img/light_shadow_background.png)
|
||||
|
||||
Next create three `Light2D's`_. You can alter their
|
||||
color in the top section. By default shadows are turned off and the `mode` is set to `add`. This
|
||||
means that each light adds its own color to whatever is underneath.
|
||||
|
||||
.. image:: img/light_shadow_all_lights_no_blob.png
|
||||
![](img/light_shadow_all_lights_no_blob.png)
|
||||
|
||||
Next add a child `Sprite` nodes, and set
|
||||
the `Sprite's`_. Each of these
|
||||
@ -128,7 +128,7 @@ itself while the `Light` shows the effect that the light has on the scene. The
|
||||
`LightOccluder2D's`
|
||||
node, which is why we want the blob to be centered on its parent `Light`.
|
||||
|
||||
.. image:: img/light_shadow_all_lights.png
|
||||
![](img/light_shadow_all_lights.png)
|
||||
|
||||
.. note:: The animations in the demo will not be covered here. See `doc_introduction_animation`
|
||||
for information on creating animations.
|
||||
@ -140,7 +140,7 @@ This is why the demo uses a `CanvasModulate` in the scene. The
|
||||
Add a `CanvasModulate` to the scene and set its color to `rgb(70, 70, 70)`.
|
||||
This will make the scene sufficiently dark to see the effects of the lights distinctly.
|
||||
|
||||
.. image:: img/light_shadow_ambient.png
|
||||
![](img/light_shadow_ambient.png)
|
||||
|
||||
Now we add the shadow casters.
|
||||
|
||||
@ -150,11 +150,11 @@ This way we can show and hide them all at the same time.
|
||||
|
||||
Each shadow caster is made of a `Sprite`
|
||||
child. For the demo the `Sprite` has a texture
|
||||
set to the `caster image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/caster.png>`_ and nothing else. The child `LightOccluder2D` is where all the magic happens. In a
|
||||
set to the `caster image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/caster.png)>`_ and nothing else. The child `LightOccluder2D` is where all the magic happens. In a
|
||||
game the `Sprite` could be more than a black box; it could be an image of whatever object is casting
|
||||
the shadow: a wall, a magical chest, or anything else.
|
||||
|
||||
.. image:: img/light_shadow_sprites.png
|
||||
![](img/light_shadow_sprites.png)
|
||||
|
||||
`LightOccluder2Ds` tell the game what shape the occluder has. They hold
|
||||
an `OccluderPolygon2D`, which is a container
|
||||
@ -173,15 +173,15 @@ To illustrate the difference, here is an image of a `LightOccluder2D` with `Clos
|
||||
set to `off` in the corresponding `OccluderPolygon2D`, so that the
|
||||
lines of the polygon can be seen:
|
||||
|
||||
.. image:: img/light_shadow_cull_disabled.png
|
||||
![](img/light_shadow_cull_disabled.png)
|
||||
|
||||
.. note:: `Cull Mode` is set to `Disabled`. All three lines cast shadows.
|
||||
|
||||
.. image:: img/light_shadow_cull_clockwise.png
|
||||
![](img/light_shadow_cull_clockwise.png)
|
||||
|
||||
.. note:: `Cull Mode` is set to `Clockwise`. Only the top and right lines cast shadows.
|
||||
|
||||
.. image:: img/light_shadow_cull_counter_clockwise.png
|
||||
![](img/light_shadow_cull_counter_clockwise.png)
|
||||
|
||||
.. note:: `Cull Mode` is set to `Counter-Clockwise`. Only the bottom line casts a shadow.
|
||||
If `Closed` was set to `on` there would be an additional vertical line on the
|
||||
@ -191,7 +191,7 @@ When you have added the `LightOccluder2Ds` the shadows still won't
|
||||
appear. You need to go back into the `Light2Ds` and under the Shadow
|
||||
section set `Enable` to `on`. This turns on shadows with hard edges like in the image below.
|
||||
|
||||
.. image:: img/light_shadow_filter0_pcf0.png
|
||||
![](img/light_shadow_filter0_pcf0.png)
|
||||
|
||||
To give the shadows that nice, soft edge look we set the variables `filter`, `filter smooth`, and
|
||||
`gradient length`. Godot supports `Percentage Closer Filtering <https://developer.nvidia.com/gpugems/GPUGems/gpugems_ch11.html>`_
|
||||
@ -200,12 +200,12 @@ a smooth shadow effect. The higher the number of samples the smoother the shadow
|
||||
look, but the slower it will run. That is why Godot provides 3-13 samples by default and allows you to choose.
|
||||
The demo uses PCF7.
|
||||
|
||||
.. image:: img/light_shadow_normal.png
|
||||
![](img/light_shadow_normal.png)
|
||||
|
||||
.. note:: This is a shadow rendered with the demo's settings. `gradient length` is set
|
||||
to `1.3`, `filter smooth` is set to `11.1`, and `filter` is set to `PCF7`.
|
||||
|
||||
.. image:: img/light_shadow_pcf13.png
|
||||
![](img/light_shadow_pcf13.png)
|
||||
|
||||
.. note:: `filter` is set to `PCF13`. Notice how the shadow becomes wider, this is because the
|
||||
distance between samples is based on the variable `filter smooth`.
|
||||
@ -215,14 +215,14 @@ This dictates how far apart the samples are. If you want the soft area to extend
|
||||
the size of `filter smooth`. However, with few samples and a large filter smooth, you can see lines
|
||||
forming between the samples.
|
||||
|
||||
.. image:: img/light_shadow_filter30.png
|
||||
![](img/light_shadow_filter30.png)
|
||||
|
||||
.. note:: `filter smooth` is set to `30`.
|
||||
|
||||
The different `Light` nodes in the demo use different values for filter smooth.
|
||||
Play around with it and see what you like.
|
||||
|
||||
.. image:: img/light_shadow_filter0.png
|
||||
![](img/light_shadow_filter0.png)
|
||||
|
||||
.. note:: `filter smooth` is set to `0`.
|
||||
|
||||
@ -230,11 +230,11 @@ Lastly, there is the variable `gradient length`. For some smooth shadows it is p
|
||||
shadow start immediately on the object, as this produces a hard edge. The gradient length variable creates
|
||||
a smooth gradient to begin the shadow to reduce the effect of the hard edge.
|
||||
|
||||
.. image:: img/light_shadow_grad0.png
|
||||
![](img/light_shadow_grad0.png)
|
||||
|
||||
.. note:: `gradient length` is set to `0`.
|
||||
|
||||
.. image:: img/light_shadow_grad10.png
|
||||
![](img/light_shadow_grad10.png)
|
||||
|
||||
.. note:: `gradient length` is set to `10`.
|
||||
|
||||
|
@ -33,20 +33,20 @@ Converting Sprites to 2D meshes
|
||||
You can take advantage of this optimization by converting a `Sprite` to a `MeshInstance2D`.
|
||||
Start with an image that contains large amounts of transparency on the edges, like this tree:
|
||||
|
||||
.. image:: img/mesh2d1.png
|
||||
![](img/mesh2d1.png)
|
||||
|
||||
Put it in a `Sprite` and select "Convert to 2D Mesh" from the menu:
|
||||
|
||||
.. image:: img/mesh2d2.png
|
||||
![](img/mesh2d2.png)
|
||||
|
||||
A dialog will appear, showing a preview of how the 2D mesh will be created:
|
||||
|
||||
.. image:: img/mesh2d3.png
|
||||
![](img/mesh2d3.png)
|
||||
|
||||
The default values are good enough for many cases, but you can change growth and simplification according to your needs:
|
||||
|
||||
.. image:: img/mesh2d4.png
|
||||
![](img/mesh2d4.png)
|
||||
|
||||
Finally, push the `Convert 2D Mesh` button and your Sprite will be replaced:
|
||||
|
||||
.. image:: img/mesh2d5.png
|
||||
![](img/mesh2d5.png)
|
||||
|
@ -19,13 +19,13 @@ Setup
|
||||
-----
|
||||
|
||||
Each example below uses the same scene setup. Start with a `KinematicBody2D` with two
|
||||
children: `Sprite` and `CollisionShape2D`. You can use the Godot icon ("icon.png")
|
||||
children: `Sprite` and `CollisionShape2D`. You can use the Godot icon ("icon.png)")
|
||||
for the Sprite's texture or use any other 2D image you have.
|
||||
|
||||
Open `Project -> Project Settings` and select the "Input Map" tab. Add the following
|
||||
input actions (see `InputEvent <doc_inputevent>` for details):
|
||||
|
||||
.. image:: img/movement_inputs.png
|
||||
![](img/movement_inputs.png)
|
||||
|
||||
8-way movement
|
||||
--------------
|
||||
@ -34,7 +34,7 @@ In this scenario, you want the user to press the four directional keys (up/left/
|
||||
or W/A/S/D) and move in the selected direction. The name "8-way movement" comes from the
|
||||
fact that the player can move diagonally by pressing two keys at the same time.
|
||||
|
||||
.. image:: img/movement_8way.gif
|
||||
![](img/movement_8way.gif)
|
||||
|
||||
Add a script to the kinematic body and add the following code:
|
||||
|
||||
@ -88,7 +88,7 @@ This type of movement is sometimes called "Asteroids-style" because it resembles
|
||||
how that classic arcade game worked. Pressing left/right rotates the character,
|
||||
while up/down moves it forward or backward in whatever direction it's facing.
|
||||
|
||||
.. image:: img/movement_rotate1.gif
|
||||
![](img/movement_rotate1.gif)
|
||||
|
||||
gdscript GDScript
|
||||
|
||||
@ -135,7 +135,7 @@ This style of movement is a variation of the previous one. This time, the direct
|
||||
is set by the mouse position instead of the keyboard. The character will always
|
||||
"look at" the mouse pointer. The forward/back inputs remain the same, however.
|
||||
|
||||
.. image:: img/movement_rotate2.gif
|
||||
![](img/movement_rotate2.gif)
|
||||
|
||||
gdscript GDScript
|
||||
|
||||
@ -176,7 +176,7 @@ Click-and-move
|
||||
This last example uses only the mouse to control the character. Clicking
|
||||
on the screen will cause the player to move to the target location.
|
||||
|
||||
.. image:: img/movement_click.gif
|
||||
![](img/movement_click.gif)
|
||||
|
||||
gdscript GDScript
|
||||
|
||||
|
@ -26,7 +26,7 @@ In this scenario, you have a collection of images, each containing one of your
|
||||
character's animation frames. For this example, we'll use the following
|
||||
animation:
|
||||
|
||||
.. image:: img/2d_animation_run_preview.gif
|
||||
![](img/2d_animation_run_preview.gif)
|
||||
|
||||
You can download the images here:
|
||||
:download:`run_animation.zip <files/run_animation.zip>`
|
||||
@ -34,7 +34,7 @@ You can download the images here:
|
||||
Unzip the images and place them in your project folder. Set up your scene tree
|
||||
with the following nodes:
|
||||
|
||||
.. image:: img/2d_animation_tree1.png
|
||||
![](img/2d_animation_tree1.png)
|
||||
|
||||
.. note:: The root node could also be `Area2D` or
|
||||
`RigidBody2D`. The animation will still be
|
||||
@ -46,18 +46,18 @@ with the following nodes:
|
||||
Now select the `AnimatedSprite` and in its *SpriteFrames* property, select
|
||||
"New SpriteFrames".
|
||||
|
||||
.. image:: img/2d_animation_new_spriteframes.png
|
||||
![](img/2d_animation_new_spriteframes.png)
|
||||
|
||||
Click on the new SpriteFrames resource and you'll see a new panel appear at the
|
||||
bottom of the editor window:
|
||||
|
||||
.. image:: img/2d_animation_spriteframes.png
|
||||
![](img/2d_animation_spriteframes.png)
|
||||
|
||||
From the FileSystem dock on the left side, drag the 8 individual images into
|
||||
the center part of the SpriteFrames panel. On the left side, change the name
|
||||
of the animation from "default" to "run".
|
||||
|
||||
.. image:: img/2d_animation_spriteframes_done.png
|
||||
![](img/2d_animation_spriteframes_done.png)
|
||||
|
||||
Back in the Inspector, check the box for the *Playing* property. You should
|
||||
now see the animation playing in the viewport. However, it is a bit slow. To
|
||||
@ -94,7 +94,7 @@ Sprite sheet with AnimatedSprite
|
||||
|
||||
You can also easily animate from a sprite sheet with the class `AnimatedSprite`. We will use this public domain sprite sheet:
|
||||
|
||||
.. image:: img/2d_animation_frog_spritesheet.png
|
||||
![](img/2d_animation_frog_spritesheet.png)
|
||||
|
||||
Right-click the image and choose "Save Image As" to download it, and then copy the image into your project folder.
|
||||
|
||||
@ -103,25 +103,25 @@ Set up your scene tree the same way you did previously when using individual ima
|
||||
|
||||
Click on the new SpriteFrames resource. This time, when the bottom panel appears, select "Add frames from a Sprite Sheet".
|
||||
|
||||
.. image:: img/2d_animation_add_from_spritesheet.png
|
||||
![](img/2d_animation_add_from_spritesheet.png)
|
||||
|
||||
You will be prompted to open a file. Select your sprite sheet.
|
||||
|
||||
A new window will open, showing your sprite sheet. The first thing you will need to do is to change the number of vertical and horizontal images in your sprite sheet. In this sprite sheet, we have four images horizontally and two images vertically.
|
||||
|
||||
.. image:: img/2d_animation_spritesheet_select_rows.png
|
||||
![](img/2d_animation_spritesheet_select_rows.png)
|
||||
|
||||
Next, select the frames from the sprite sheet that you want to include in your animation. We will select the top four, then click "Add 4 frames" to create the animation.
|
||||
|
||||
.. image:: img/2d_animation_spritesheet_selectframes.png
|
||||
![](img/2d_animation_spritesheet_selectframes.png)
|
||||
|
||||
You will now see your animation under the list of animations in the bottom panel. Double click on default to change the name of the animation to jump.
|
||||
|
||||
.. image:: img/2d_animation_spritesheet_animation.png
|
||||
![](img/2d_animation_spritesheet_animation.png)
|
||||
|
||||
Finally, check Playing on the AnimatedSprite in the inspector to see your frog jump!
|
||||
|
||||
.. image:: img/2d_animation_play_spritesheet_animation.png
|
||||
![](img/2d_animation_play_spritesheet_animation.png)
|
||||
|
||||
|
||||
Sprite sheet with AnimationPlayer
|
||||
@ -133,7 +133,7 @@ change from texture to texture with `AnimationPlayer`.
|
||||
|
||||
Consider this sprite sheet, which contains 6 frames of animation:
|
||||
|
||||
.. image:: img/2d_animation_player-run.png
|
||||
![](img/2d_animation_player-run.png)
|
||||
|
||||
Right-click the image and choose "Save Image As" to download, then copy the
|
||||
image into your project folder.
|
||||
@ -141,7 +141,7 @@ image into your project folder.
|
||||
Our goal is to display these images one after another in a loop. Start by
|
||||
setting up your scene tree:
|
||||
|
||||
.. image:: img/2d_animation_tree2.png
|
||||
![](img/2d_animation_tree2.png)
|
||||
|
||||
.. note:: The root node could also be `Area2D` or
|
||||
`RigidBody2D`. The animation will still be
|
||||
@ -156,7 +156,7 @@ expand the *Animation* section in the Inspector and set the *Hframes* to `6`.
|
||||
*Hframes* and *Vframes* are the number of horizontal and vertical frames in
|
||||
your sprite sheet.
|
||||
|
||||
.. image:: img/2d_animation_setframes.png
|
||||
![](img/2d_animation_setframes.png)
|
||||
|
||||
Now try changing the value of the *Frame* property. You'll see that it ranges
|
||||
from `0` to `5` and the image displayed by the Sprite changes accordingly.
|
||||
@ -166,21 +166,21 @@ Select the `AnimationPlayer` and click the "Animation" button followed by
|
||||
"New". Name the new animation "walk". Set the animation length to `0.6` and
|
||||
click the "Loop" button so that our animation will repeat.
|
||||
|
||||
.. image:: img/2d_animation_new_animation.png
|
||||
![](img/2d_animation_new_animation.png)
|
||||
|
||||
Now select the `Sprite` node and click the key icon to add a new track.
|
||||
|
||||
.. image:: img/2d_animation_new_track.png
|
||||
![](img/2d_animation_new_track.png)
|
||||
|
||||
Continue adding frames at each point in the timeline (`0.1` seconds by
|
||||
default), until you have all the frames from 0 to 5. You'll see the frames
|
||||
actually appearing in the animation track:
|
||||
|
||||
.. image:: img/2d_animation_full_animation.png
|
||||
![](img/2d_animation_full_animation.png)
|
||||
|
||||
Press "Play" on the animation to see how it looks.
|
||||
|
||||
.. image:: img/2d_animation_running.gif
|
||||
![](img/2d_animation_running.gif)
|
||||
|
||||
Controlling an AnimationPlayer animation
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
@ -52,7 +52,7 @@ Transform order
|
||||
For a coordinate in CanvasItem local properties to become an actual
|
||||
screen coordinate, the following chain of transforms must be applied:
|
||||
|
||||
.. image:: img/viewport_transforms2.png
|
||||
![](img/viewport_transforms2.png)
|
||||
|
||||
Transform functions
|
||||
-------------------
|
||||
|
@ -52,7 +52,7 @@ counter and pause button can also be created at layer "1".
|
||||
|
||||
Here's a diagram of how it looks:
|
||||
|
||||
.. image:: img/canvaslayers.png
|
||||
![](img/canvaslayers.png)
|
||||
|
||||
CanvasLayers are independent of tree order, and they only depend on
|
||||
their layer number, so they can be instantiated when needed.
|
||||
|
@ -186,7 +186,7 @@ gdscript GDScript
|
||||
|
||||
Result:
|
||||
|
||||
.. image:: img/result_drawarc.png
|
||||
![](img/result_drawarc.png)
|
||||
|
||||
Arc polygon function
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
@ -210,7 +210,7 @@ gdscript GDScript
|
||||
draw_polygon(points_arc, colors)
|
||||
```
|
||||
|
||||
.. image:: img/result_drawarc_poly.png
|
||||
![](img/result_drawarc_poly.png)
|
||||
|
||||
Dynamic custom drawing
|
||||
^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -31,7 +31,7 @@ are provided via node properties in CPUParticles2D (with the exception of the tr
|
||||
You can convert a Particles2D node into a CPUParticles2D node by clicking on the node in the
|
||||
inspector, and selecting "Convert to CPUParticles2D" in the "Particles" menu of the toolbar.
|
||||
|
||||
.. image:: img/particles_convert.png
|
||||
![](img/particles_convert.png)
|
||||
|
||||
The rest of this tutorial is going to use the Particles2D node. First, add a Particles2D
|
||||
node to your scene. After creating that node you will notice that only a white dot was created,
|
||||
@ -45,12 +45,12 @@ To add a process material to your particles node, go to `Process Material` in
|
||||
your inspector panel. Click on the box next to `Material`, and from the dropdown
|
||||
menu select `New ParticlesMaterial`.
|
||||
|
||||
.. image:: img/particles_material.png
|
||||
![](img/particles_material.png)
|
||||
|
||||
Your Particles2D node should now be emitting
|
||||
white points downward.
|
||||
|
||||
.. image:: img/particles1.png
|
||||
![](img/particles1.png)
|
||||
|
||||
Texture
|
||||
~~~~~~~
|
||||
@ -59,7 +59,7 @@ A particle system uses a single texture (in the future this might be
|
||||
extended to animated textures via spritesheet). The texture is set via
|
||||
the relevant texture property:
|
||||
|
||||
.. image:: img/particles2.png
|
||||
![](img/particles2.png)
|
||||
|
||||
Time parameters
|
||||
---------------
|
||||
@ -72,11 +72,11 @@ ends, a new particle is created to replace it.
|
||||
|
||||
Lifetime: 0.5
|
||||
|
||||
.. image:: img/paranim14.gif
|
||||
![](img/paranim14.gif)
|
||||
|
||||
Lifetime: 4.0
|
||||
|
||||
.. image:: img/paranim15.gif
|
||||
![](img/paranim15.gif)
|
||||
|
||||
One Shot
|
||||
~~~~~~~~
|
||||
@ -113,7 +113,7 @@ this, and forces particles to be emitted all together. Ranges are:
|
||||
Values in the middle are also allowed. This feature is useful for
|
||||
creating explosions or sudden bursts of particles:
|
||||
|
||||
.. image:: img/paranim18.gif
|
||||
![](img/paranim18.gif)
|
||||
|
||||
Randomness
|
||||
~~~~~~~~~~
|
||||
@ -161,12 +161,12 @@ By default this option is on, and it means that the space that particles
|
||||
are emitted to is relative to the node. If the node is moved, all
|
||||
particles are moved with it:
|
||||
|
||||
.. image:: img/paranim20.gif
|
||||
![](img/paranim20.gif)
|
||||
|
||||
If disabled, particles will emit to global space, meaning that if the
|
||||
node is moved, already emitted particles are not affected:
|
||||
|
||||
.. image:: img/paranim21.gif
|
||||
![](img/paranim21.gif)
|
||||
|
||||
Draw Order
|
||||
~~~~~~~~~~
|
||||
@ -185,13 +185,13 @@ This is the base direction at which particles emit. The default is
|
||||
`Vector3(1, 0, 0)` which makes particles emit to the right. However,
|
||||
with the default gravity settings, particles will go straight down.
|
||||
|
||||
.. image:: img/direction1.png
|
||||
![](img/direction1.png)
|
||||
|
||||
For this property to be noticeable, you need an *initial velocity* greater
|
||||
than 0. Here, we set the initial velocity to 40. You'll notice that
|
||||
particles emit toward the right, then go down because of gravity.
|
||||
|
||||
.. image:: img/direction2.png
|
||||
![](img/direction2.png)
|
||||
|
||||
Spread
|
||||
~~~~~~
|
||||
@ -201,7 +201,7 @@ either direction to the base `Direction`. A spread of `180` will emit
|
||||
in all directions (+/- 180). For spread to do anything the "Initial Velocity"
|
||||
parameter must be greater than 0.
|
||||
|
||||
.. image:: img/paranim3.gif
|
||||
![](img/paranim3.gif)
|
||||
|
||||
Flatness
|
||||
~~~~~~~~
|
||||
@ -213,7 +213,7 @@ Gravity
|
||||
|
||||
The gravity applied to every particle.
|
||||
|
||||
.. image:: img/paranim7.gif
|
||||
![](img/paranim7.gif)
|
||||
|
||||
Initial Velocity
|
||||
~~~~~~~~~~~~~~~~
|
||||
@ -222,7 +222,7 @@ Initial velocity is the speed at which particles will be emitted (in
|
||||
pixels/sec). Speed might later be modified by gravity or other
|
||||
accelerations (as described further below).
|
||||
|
||||
.. image:: img/paranim4.gif
|
||||
![](img/paranim4.gif)
|
||||
|
||||
Angular Velocity
|
||||
~~~~~~~~~~~~~~~~
|
||||
@ -235,14 +235,14 @@ Spin Velocity
|
||||
Spin velocity is the speed at which particles turn around their center
|
||||
(in degrees/sec).
|
||||
|
||||
.. image:: img/paranim5.gif
|
||||
![](img/paranim5.gif)
|
||||
|
||||
Orbit Velocity
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
Orbit velocity is used to make particles turn around their center.
|
||||
|
||||
.. image:: img/paranim6.gif
|
||||
![](img/paranim6.gif)
|
||||
|
||||
Linear Acceleration
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@ -255,7 +255,7 @@ Radial Acceleration
|
||||
If this acceleration is positive, particles are accelerated away from
|
||||
the center. If negative, they are absorbed towards it.
|
||||
|
||||
.. image:: img/paranim8.gif
|
||||
![](img/paranim8.gif)
|
||||
|
||||
Tangential Acceleration
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -263,7 +263,7 @@ Tangential Acceleration
|
||||
This acceleration will use the tangent vector to the center. Combining
|
||||
with radial acceleration can do nice effects.
|
||||
|
||||
.. image:: img/paranim9.gif
|
||||
![](img/paranim9.gif)
|
||||
|
||||
Damping
|
||||
~~~~~~~
|
||||
@ -272,7 +272,7 @@ Damping applies friction to the particles, forcing them to stop. It is
|
||||
especially useful for sparks or explosions, which usually begin with a
|
||||
high linear velocity and then stop as they fade.
|
||||
|
||||
.. image:: img/paranim10.gif
|
||||
![](img/paranim10.gif)
|
||||
|
||||
Angle
|
||||
~~~~~
|
||||
@ -280,14 +280,14 @@ Angle
|
||||
Determines the initial angle of the particle (in degrees). This parameter
|
||||
is mostly useful randomized.
|
||||
|
||||
.. image:: img/paranim11.gif
|
||||
![](img/paranim11.gif)
|
||||
|
||||
Scale
|
||||
~~~~~
|
||||
|
||||
Determines the initial scale of the particles.
|
||||
|
||||
.. image:: img/paranim12.gif
|
||||
![](img/paranim12.gif)
|
||||
|
||||
Color
|
||||
~~~~~
|
||||
@ -311,15 +311,15 @@ These can be generated from textures in your project.
|
||||
Ensure that a ParticlesMaterial is set, and the Particles2D node is selected.
|
||||
A "Particles" menu should appear in the Toolbar:
|
||||
|
||||
.. image:: img/emission_shapes1.png
|
||||
![](img/emission_shapes1.png)
|
||||
|
||||
Open it and select "Load Emission Mask":
|
||||
|
||||
.. image:: img/emission_shapes2.png
|
||||
![](img/emission_shapes2.png)
|
||||
|
||||
Then select which texture you want to use as your mask:
|
||||
|
||||
.. image:: img/emission_shapes3.png
|
||||
![](img/emission_shapes3.png)
|
||||
|
||||
A dialog box with several settings will appear.
|
||||
|
||||
@ -331,18 +331,18 @@ Three types of emission masks can be generated from a texture:
|
||||
- Solid Pixels: Particles will spawn from any area of the texture,
|
||||
excluding transparent areas.
|
||||
|
||||
.. image:: img/emission_mask_solid.gif
|
||||
![](img/emission_mask_solid.gif)
|
||||
|
||||
- Border Pixels: Particles will spawn from the outer edges of the texture.
|
||||
|
||||
.. image:: img/emission_mask_border.gif
|
||||
![](img/emission_mask_border.gif)
|
||||
|
||||
- Directed Border Pixels: Similar to Border Pixels, but adds extra
|
||||
information to the mask to give particles the ability to emit away
|
||||
from the borders. Note that an `Initial Velocity` will need to
|
||||
be set in order to utilize this.
|
||||
|
||||
.. image:: img/emission_mask_directed_border.gif
|
||||
![](img/emission_mask_directed_border.gif)
|
||||
|
||||
Emission Colors
|
||||
~~~~~~~~~~~~~~~
|
||||
@ -351,7 +351,7 @@ Emission Colors
|
||||
|
||||
Once you click "OK", the mask will be generated and set to the ParticlesMaterial, under the `Emission Shape` section:
|
||||
|
||||
.. image:: img/emission_shapes4.png
|
||||
![](img/emission_shapes4.png)
|
||||
|
||||
All of the values within this section have been automatically generated by the
|
||||
"Load Emission Mask" menu, so they should generally be left alone.
|
||||
|
@ -15,7 +15,7 @@ optimized for drawing large numbers of tiles. Finally, you can add collision,
|
||||
occlusion, and navigation shapes to tiles, adding additional functionality to
|
||||
the TileMap.
|
||||
|
||||
.. image:: img/tileset_draw_atlas.png
|
||||
![](img/tileset_draw_atlas.png)
|
||||
|
||||
Project setup
|
||||
-------------
|
||||
@ -24,7 +24,7 @@ This demo will use the following tiles taken from Kenney's "Abstract Platformer"
|
||||
art pack. You can find the complete set `here <https://kenney.nl/assets/abstract-platformer>`_
|
||||
but for this demo we'll stick to this small set.
|
||||
|
||||
.. image:: img/tilesheet.png
|
||||
![](img/tilesheet.png)
|
||||
|
||||
Create a new project and place the above image in the project folder.
|
||||
|
||||
@ -40,12 +40,12 @@ Add a new `TileMap` node to the scene. By default, a TileMap
|
||||
uses a square grid of tiles. You can also use a perspective-based "Isometric" mode
|
||||
or define your own custom tile shape.
|
||||
|
||||
.. image:: img/tilemap_mode.png
|
||||
![](img/tilemap_mode.png)
|
||||
|
||||
Under the "Cell" section in the Inspector are many properties you can adjust to
|
||||
customize your tilemap's behavior:
|
||||
|
||||
.. image:: img/tilemap_size.png
|
||||
![](img/tilemap_size.png)
|
||||
|
||||
- `Cell Size`
|
||||
This defines the size of the grid. This should match the pixel size
|
||||
@ -79,32 +79,32 @@ runs, the TileMap combines the individual tiles into a single object.
|
||||
To add a new TileSet, click on the "Tile Set" property and select "New
|
||||
TileSet".
|
||||
|
||||
.. image:: img/tilemap_add_tileset.png
|
||||
![](img/tilemap_add_tileset.png)
|
||||
|
||||
Click on the TileSet property, and the "TileSet" panel will open at the bottom
|
||||
of the editor window:
|
||||
|
||||
.. image:: img/tilemap_tool.png
|
||||
![](img/tilemap_tool.png)
|
||||
|
||||
First, you need to add the texture(s) that you'll use for the tiles. Click the
|
||||
"Add Texture(s) to TileSet" button and select the `tilesheet.png` image.
|
||||
"Add Texture(s) to TileSet" button and select the `tilesheet.png)` image.
|
||||
|
||||
Next, click "New Single Tile" and drag in the image to select the tile you want.
|
||||
Click the "Enable Snap" button to make it easier to select the entire tile. A
|
||||
yellow rectangle appears around the selected tile.
|
||||
|
||||
.. image:: img/tilemap_add_tile.png
|
||||
![](img/tilemap_add_tile.png)
|
||||
|
||||
Click on the TileMap in the scene tree, and you'll see that the newly created
|
||||
tile now appears on the right side. Click in the viewport and you can place
|
||||
tiles. Right-click to remove them.
|
||||
|
||||
.. image:: img/tilemap_draw.png
|
||||
![](img/tilemap_draw.png)
|
||||
|
||||
It's easy to accidentally select and move the tilemap node. To avoid this, use
|
||||
the node's lock button:
|
||||
|
||||
.. image:: img/tile_lock.png
|
||||
![](img/tile_lock.png)
|
||||
|
||||
Collision shapes
|
||||
----------------
|
||||
@ -119,7 +119,7 @@ tool. Click the tile you previously defined (outlined in yellow). Select the
|
||||
still have grid snap enabled, then click and drag in the tile. A square
|
||||
collision shape appears in light blue:
|
||||
|
||||
.. image:: img/tileset_add_collision.png
|
||||
![](img/tileset_add_collision.png)
|
||||
|
||||
You can add occlusion and navigation shapes to the tile in the same way.
|
||||
|
||||
@ -132,13 +132,13 @@ tiles from the group.
|
||||
|
||||
Click "New Atlas" and drag to select the entire tile sheet.
|
||||
|
||||
.. image:: img/tileset_atlas.png
|
||||
![](img/tileset_atlas.png)
|
||||
|
||||
If you haven't already, make sure to change the "Step" in the snap settings to
|
||||
`(64, 64)`, or your tiles may be chopped into smaller pieces. You can find
|
||||
this in the Inspector:
|
||||
|
||||
.. image:: img/tileset_snap.png
|
||||
![](img/tileset_snap.png)
|
||||
|
||||
Once you've defined the atlas you can add collision shapes to the individual
|
||||
tiles as before. You can also click "Icon" to select one of the tiles to represent
|
||||
@ -147,7 +147,7 @@ the atlas.
|
||||
Back in the TileMap, you can select the atlas tile and you'll see all of the
|
||||
tiles it contains:
|
||||
|
||||
.. image:: img/tileset_draw_atlas.png
|
||||
![](img/tileset_draw_atlas.png)
|
||||
|
||||
In addition to saving time when defining the tiles, this can help by grouping
|
||||
similar tiles together when you're working with a large number of tiles.
|
||||
@ -221,7 +221,7 @@ Key:
|
||||
- Red: "on"
|
||||
- White: "off"
|
||||
|
||||
.. image:: img/autotile_template_2x2.png
|
||||
![](img/autotile_template_2x2.png)
|
||||
|
||||
3x3 (minimal)
|
||||
~~~~~~~~~~~~~
|
||||
@ -254,7 +254,7 @@ Key:
|
||||
- Red: "on"
|
||||
- White: "off"
|
||||
|
||||
.. image:: img/autotile_template_3x3_minimal.png
|
||||
![](img/autotile_template_3x3_minimal.png)
|
||||
|
||||
|
||||
**Template - Generic 16 tiles:**
|
||||
@ -268,7 +268,7 @@ Key:
|
||||
- White: "off"
|
||||
- Blue-checkered: "ignore"
|
||||
|
||||
.. image:: img/autotile_template_3x3_minimal_16.png
|
||||
![](img/autotile_template_3x3_minimal_16.png)
|
||||
|
||||
|
||||
**Template - Top-down floor in 3/4 perspective:**
|
||||
@ -281,17 +281,17 @@ Key (applies to the four templates below):
|
||||
- Grey: hidden due to overlap
|
||||
- Transparent: air
|
||||
|
||||
.. image:: img/autotile_template_3x3_minimal_topdown_floor.png
|
||||
![](img/autotile_template_3x3_minimal_topdown_floor.png)
|
||||
|
||||
**Template - Top-down wall in 3/4 perspective:**
|
||||
|
||||
.. image:: img/autotile_template_3x3_minimal_topdown_walls.png
|
||||
![](img/autotile_template_3x3_minimal_topdown_walls.png)
|
||||
|
||||
**Template - Top-down wall in 3/4 perspective (thick walls):**
|
||||
|
||||
When using this template, set the TileSet subtile size to `Vector2(64, 88)`.
|
||||
|
||||
.. image:: img/autotile_template_3x3_minimal_topdown_walls_thick.png
|
||||
![](img/autotile_template_3x3_minimal_topdown_walls_thick.png)
|
||||
|
||||
**Template - Top-down wall in 3/4 perspective (tall walls):**
|
||||
|
||||
@ -299,7 +299,7 @@ When using this template, set the "Snap Options" Step to `Vector2(64, 184)`
|
||||
and the "Selected Tile" Texture offset to height minus the cell size.
|
||||
This means the texture offset should be `Vector2(0, -120)`:
|
||||
|
||||
.. image:: img/autotile_template_3x3_minimal_topdown_walls_tall.png
|
||||
![](img/autotile_template_3x3_minimal_topdown_walls_tall.png)
|
||||
|
||||
3x3
|
||||
~~~
|
||||
@ -351,4 +351,4 @@ Tips and tricks
|
||||
- Tools such as copy, paste, and bucket fill, can be found in the "TileMap"
|
||||
menu in the upper-right.
|
||||
|
||||
.. image:: img/tilemap_menu.png
|
||||
![](img/tilemap_menu.png)
|
||||
|
@ -18,7 +18,7 @@ demo project.
|
||||
Label3D
|
||||
-------
|
||||
|
||||
.. image:: img/label_3d.png
|
||||
![](img/label_3d.png)
|
||||
|
||||
Label3D behaves like a label node but in a 3D space. Unlike label
|
||||
node this can not inherit properties of a GUI theme. However its
|
||||
@ -36,7 +36,7 @@ for more information.
|
||||
Text mesh
|
||||
---------
|
||||
|
||||
.. image:: img/text_mesh.png
|
||||
![](img/text_mesh.png)
|
||||
|
||||
Text meshes have similarities to Label3D. They display text in a 3D
|
||||
scene, and will use the same DynamicFont subresource. However text is 3D and
|
||||
@ -44,9 +44,9 @@ has the properties of a mesh. A text mesh cast shadows onto the environment
|
||||
and can have a material applied to it. Here is an example of a texture and
|
||||
how it's applied to the mesh.
|
||||
|
||||
.. image:: img/text_mesh_texture.png
|
||||
![](img/text_mesh_texture.png)
|
||||
|
||||
.. image:: img/text_mesh_textured.png
|
||||
![](img/text_mesh_textured.png)
|
||||
|
||||
There are two limitations to text mesh. It can't use bitmap fonts, or fonts
|
||||
with self intersection.
|
||||
|
@ -42,7 +42,7 @@ that lighting is on an unwrapped texture, so transitions and resolution may not
|
||||
be that good. GIProbe looks less accurate (as it's an approximation), but
|
||||
smoother overall.
|
||||
|
||||
.. image:: img/baked_light_comparison.png
|
||||
![](img/baked_light_comparison.png)
|
||||
|
||||
Setting up
|
||||
----------
|
||||
@ -64,7 +64,7 @@ across reimports, so it will only be regenerated when needed.
|
||||
Select the imported scene in the filesystem dock, then go to the **Import** dock.
|
||||
There, the following option can be modified:
|
||||
|
||||
.. image:: img/baked_light_import.png
|
||||
![](img/baked_light_import.png)
|
||||
|
||||
The **Light Baking** mode needs to be set to **Gen Lightmaps**. A texel size
|
||||
in world units must also be provided, as this will determine the
|
||||
@ -91,7 +91,7 @@ Unwrap from within Godot
|
||||
Godot has an option to unwrap meshes and visualize the UV channels.
|
||||
It can be found in the Mesh menu:
|
||||
|
||||
.. image:: img/baked_light_mesh_menu.png
|
||||
![](img/baked_light_mesh_menu.png)
|
||||
|
||||
This will generate a second set of UV2 coordinates which can be used for baking,
|
||||
and it will also set the texture size automatically.
|
||||
@ -107,12 +107,12 @@ so having it unwrapped before import can be faster.
|
||||
|
||||
Simply do an unwrap on the second UV2 layer.
|
||||
|
||||
.. image:: img/baked_light_blender.png
|
||||
![](img/baked_light_blender.png)
|
||||
|
||||
Then import the 3D scene normally. Remember you will need to set the texture
|
||||
size on the mesh after import.
|
||||
|
||||
.. image:: img/baked_light_lmsize.png
|
||||
![](img/baked_light_lmsize.png)
|
||||
|
||||
If you use external meshes on import, the size will be kept.
|
||||
Be wary that most unwrappers in 3D DCCs are not quality oriented, as they are
|
||||
@ -125,7 +125,7 @@ Checking UV2
|
||||
In the mesh menu mentioned before, the UV2 texture coordinates can be visualized.
|
||||
Make sure, if something is failing, to check that the meshes have these UV2 coordinates:
|
||||
|
||||
.. image:: img/baked_light_uvchannel.png
|
||||
![](img/baked_light_uvchannel.png)
|
||||
|
||||
Setting up the scene
|
||||
--------------------
|
||||
@ -134,7 +134,7 @@ Before anything is done, a **BakedLightmap** node needs to be added to a scene.
|
||||
This will enable light baking on all nodes (and sub-nodes) in that scene, even
|
||||
on instanced scenes.
|
||||
|
||||
.. image:: img/baked_light_scene.png
|
||||
![](img/baked_light_scene.png)
|
||||
|
||||
A sub-scene can be instanced several times, as this is supported by the baker, and
|
||||
each will be assigned a lightmap of its own (just make sure to respect the rule
|
||||
@ -147,7 +147,7 @@ Lightmap needs an approximate volume of the area affected because it uses it to
|
||||
transfer light to dynamic objects inside it (more on that later). Just
|
||||
cover the scene with the volume as you do with `GIProbe`:
|
||||
|
||||
.. image:: img/baked_light_bounds.png
|
||||
![](img/baked_light_bounds.png)
|
||||
|
||||
Setting up meshes
|
||||
~~~~~~~~~~~~~~~~~
|
||||
@ -155,7 +155,7 @@ Setting up meshes
|
||||
For a **MeshInstance** node to take part in the baking process, it needs to have
|
||||
the **Use in Baked Light** property enabled.
|
||||
|
||||
.. image:: img/baked_light_use.png
|
||||
![](img/baked_light_use.png)
|
||||
|
||||
When auto-generating lightmaps on scene import, this is enabled automatically.
|
||||
|
||||
@ -169,7 +169,7 @@ that light will be baked.
|
||||
Lights can be disabled (no bake) or be fully baked (direct and indirect). This
|
||||
can be controlled from the **Bake Mode** menu in lights:
|
||||
|
||||
.. image:: img/baked_light_bake_mode.png
|
||||
![](img/baked_light_bake_mode.png)
|
||||
|
||||
The modes are:
|
||||
|
||||
@ -220,7 +220,7 @@ This size is used to provide softer shadows depending on the distance between
|
||||
the shadow caster and the object receiving the shadow. This mimics real life
|
||||
shadow appearance:
|
||||
|
||||
.. image:: img/baked_light_omnilight_size.png
|
||||
![](img/baked_light_omnilight_size.png)
|
||||
|
||||
The light's **Size** property is ignored for real-time shadows; it will only affect baked
|
||||
shadows. When the **Size** property is changed, lightmaps must be baked again to
|
||||
@ -232,7 +232,7 @@ Baking
|
||||
To begin the bake process, just push the **Bake Lightmaps** button on top
|
||||
when selecting the BakedLightmap node:
|
||||
|
||||
.. image:: img/baked_light_bake.png
|
||||
![](img/baked_light_bake.png)
|
||||
|
||||
This can take from seconds to minutes (or hours) depending on scene size, bake
|
||||
method and quality selected.
|
||||
@ -375,4 +375,4 @@ automatic, so you don't have to do anything. Just move your objects around, and
|
||||
they will be lit accordingly. Of course, you have to make sure you set up your
|
||||
scene bounds accordingly or it won't work.
|
||||
|
||||
.. image:: img/baked_light_indirect.gif
|
||||
![](img/baked_light_indirect.gif)
|
||||
|
@ -21,7 +21,7 @@ Interior environments can be created by using inverted primitives.
|
||||
`TrenchBroom <https://kristianduske.com/trenchbroom/>`__ and import
|
||||
them in Godot.
|
||||
|
||||
.. image:: img/csg.gif
|
||||
![](img/csg.gif)
|
||||
|
||||
Introduction to CSG nodes
|
||||
-------------------------
|
||||
@ -37,9 +37,9 @@ the CSG nodes:
|
||||
- `CSGMesh`
|
||||
- `CSGCombiner`
|
||||
|
||||
.. image:: img/csg_nodes.png
|
||||
![](img/csg_nodes.png)
|
||||
|
||||
.. image:: img/csg_mesh.png
|
||||
![](img/csg_mesh.png)
|
||||
|
||||
CSG tools features
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
@ -52,9 +52,9 @@ Every CSG node supports 3 kinds of boolean operations:
|
||||
- **Subtraction:** The second shape is subtracted from the first, leaving a dent
|
||||
with its shape.
|
||||
|
||||
.. image:: img/csg_operation_menu.png
|
||||
![](img/csg_operation_menu.png)
|
||||
|
||||
.. image:: img/csg_operation.png
|
||||
![](img/csg_operation.png)
|
||||
|
||||
CSGPolygon
|
||||
~~~~~~~~~~
|
||||
@ -67,9 +67,9 @@ The `CSGPolygon` node extrude along a Polygon drawn in
|
||||
- **Path:** Extruded along a Path node. This operation is commonly called
|
||||
lofting.
|
||||
|
||||
.. image:: img/csg_poly_mode.png
|
||||
![](img/csg_poly_mode.png)
|
||||
|
||||
.. image:: img/csg_poly.png
|
||||
![](img/csg_poly.png)
|
||||
|
||||
.. note:: The **Path** mode must be provided with a `Path`
|
||||
node to work. In the Path node, draw the path and the polygon in
|
||||
@ -88,7 +88,7 @@ supported. There are some restrictions for geometry:
|
||||
- it must not contain internal faces,
|
||||
- every edge must connect to only two other faces.
|
||||
|
||||
.. image:: img/csg_custom_mesh.png
|
||||
![](img/csg_custom_mesh.png)
|
||||
|
||||
CSGCombiner
|
||||
~~~~~~~~~~~
|
||||
@ -133,14 +133,14 @@ Create a scene with a Spatial node as root node.
|
||||
the 3D viewport menu, or add a DirectionalLight node to help you see
|
||||
clearly.
|
||||
|
||||
.. image:: img/csg_overdraw.png
|
||||
![](img/csg_overdraw.png)
|
||||
|
||||
Create a CSGBox and name it `room`, enable **Invert Faces** and change the
|
||||
dimensions of your room.
|
||||
|
||||
.. image:: img/csg_room.png
|
||||
![](img/csg_room.png)
|
||||
|
||||
.. image:: img/csg_room_invert.png
|
||||
![](img/csg_room_invert.png)
|
||||
|
||||
Next, create a CSGCombiner and name it `desk`.
|
||||
|
||||
@ -153,7 +153,7 @@ A desk has one surface and 4 legs:
|
||||
|
||||
Adjust their placement to resemble a desk.
|
||||
|
||||
.. image:: img/csg_desk.png
|
||||
![](img/csg_desk.png)
|
||||
|
||||
.. note:: CSG nodes inside a CSGCombiner will only process their operation
|
||||
within the combiner. Therefore, CSGCombiners are used to organize
|
||||
@ -165,22 +165,22 @@ Our bed consists of 3 parts: the bed, the mattress and a pillow. Create a CSGBox
|
||||
and adjust its dimension for the bed. Create another CSGBox and adjust its
|
||||
dimension for the mattress.
|
||||
|
||||
.. image:: img/csg_bed_mat.png
|
||||
![](img/csg_bed_mat.png)
|
||||
|
||||
We will create another CSGCombiner named `pillow` as the child of `bed`.
|
||||
The scene tree should look like this:
|
||||
|
||||
.. image:: img/csg_bed_tree.png
|
||||
![](img/csg_bed_tree.png)
|
||||
|
||||
We will combine 3 CSGSphere nodes in **Union** mode to form a pillow. Scale the
|
||||
Y axis of the spheres and enable **Smooth Faces**.
|
||||
|
||||
.. image:: img/csg_pillow_smooth.png
|
||||
![](img/csg_pillow_smooth.png)
|
||||
|
||||
Select the `pillow` node and switch the mode to **Subtraction**; the combined
|
||||
spheres will cut a hole into the mattress.
|
||||
|
||||
.. image:: img/csg_pillow_hole.png
|
||||
![](img/csg_pillow_hole.png)
|
||||
|
||||
Try to re-parent the `pillow` node to the root `Spatial` node; the hole will
|
||||
disappear.
|
||||
@ -193,7 +193,7 @@ disappear.
|
||||
Undo the re-parent after observing the effect. The bed you've built should look
|
||||
like this:
|
||||
|
||||
.. image:: img/csg_bed.png
|
||||
![](img/csg_bed.png)
|
||||
|
||||
Create a CSGCombiner and name it `lamp`.
|
||||
|
||||
@ -201,46 +201,46 @@ A lamp consists of 3 parts: the stand, the pole and the lampshade.
|
||||
Create a CSGCylinder, enable the **Cone** option and make it the stand. Create
|
||||
another CSGCylinder and adjust the dimensions to use it as a pole.
|
||||
|
||||
.. image:: img/csg_lamp_pole_stand.png
|
||||
![](img/csg_lamp_pole_stand.png)
|
||||
|
||||
We will use a CSGPolygon for the lampshade. Use the **Spin** mode for the
|
||||
CSGPolygon and draw a `trapezoid <https://en.wikipedia.org/wiki/Trapezoid>`_
|
||||
while in **Front View** (numeric keypad 1); this shape will extrude around the
|
||||
origin and form the lampshade.
|
||||
|
||||
.. image:: img/csg_lamp_spin.png
|
||||
![](img/csg_lamp_spin.png)
|
||||
|
||||
.. image:: img/csg_lamp_polygon.png
|
||||
![](img/csg_lamp_polygon.png)
|
||||
|
||||
.. image:: img/csg_lamp_extrude.png
|
||||
![](img/csg_lamp_extrude.png)
|
||||
|
||||
Adjust the placement of the 3 parts to make it look like a lamp.
|
||||
|
||||
.. image:: img/csg_lamp.png
|
||||
![](img/csg_lamp.png)
|
||||
|
||||
Create a CSGCombiner and name it `bookshelf`.
|
||||
|
||||
We will use 3 CSGBox nodes for the bookshelf. Create a CSGBox and adjust its
|
||||
dimensions; this will be the size of the bookshelf.
|
||||
|
||||
.. image:: img/csg_shelf_big.png
|
||||
![](img/csg_shelf_big.png)
|
||||
|
||||
Duplicate the CSGBox and shorten the dimensions of each axis and change the mode
|
||||
to **Subtraction**.
|
||||
|
||||
.. image:: img/csg_shelf_subtract.png
|
||||
![](img/csg_shelf_subtract.png)
|
||||
|
||||
.. image:: img/csg_shelf_subtract_menu.png
|
||||
![](img/csg_shelf_subtract_menu.png)
|
||||
|
||||
You've almost built a shelf. Create one more CSGBox for dividing the shelf into
|
||||
two levels.
|
||||
|
||||
.. image:: img/csg_shelf.png
|
||||
![](img/csg_shelf.png)
|
||||
|
||||
Position your furniture in your room as you like and your scene should look
|
||||
this:
|
||||
|
||||
.. image:: img/csg_room_result.png
|
||||
![](img/csg_room_result.png)
|
||||
|
||||
You've successfully prototyped a room level with the CSG tools in Godot.
|
||||
CSG tools can be used for designing all kinds of levels, such as a maze
|
||||
|
@ -19,7 +19,7 @@ Camera node
|
||||
|
||||
An Environment can be set to a camera. It will have priority over any other setting.
|
||||
|
||||
.. image:: img/environment_camera.png
|
||||
![](img/environment_camera.png)
|
||||
|
||||
This is mostly useful when wanting to override an existing environment,
|
||||
but in general it's a better idea to use the option below.
|
||||
@ -30,7 +30,7 @@ WorldEnvironment node
|
||||
The WorldEnvironment node can be added to any scene, but only one can exist per
|
||||
active scene tree. Adding more than one will result in a warning.
|
||||
|
||||
.. image:: img/environment_world.png
|
||||
![](img/environment_world.png)
|
||||
|
||||
Any Environment added has higher priority than the default Environment
|
||||
(explained below). This means it can be overridden on a per-scene basis,
|
||||
@ -43,7 +43,7 @@ A default environment can be set, which acts as a fallback when no Environment
|
||||
was set to a Camera or WorldEnvironment.
|
||||
Just head to Project Settings -> Rendering -> Environment:
|
||||
|
||||
.. image:: img/environment_default.png
|
||||
![](img/environment_default.png)
|
||||
|
||||
New projects created from the Project Manager come with a default environment
|
||||
(`default_env.tres`). If one needs to be created, save it to disk before
|
||||
@ -63,7 +63,7 @@ the screen where objects were not drawn). In Godot 3.0, the background not only
|
||||
serves the purpose of displaying an image or color, it can also change how objects
|
||||
are affected by ambient and reflected light.
|
||||
|
||||
.. image:: img/environment_background1.png
|
||||
![](img/environment_background1.png)
|
||||
|
||||
There are many ways to set the background:
|
||||
|
||||
@ -84,7 +84,7 @@ color multiplied by the material albedo) and then one obtained from the *Sky*
|
||||
(as described before, but a sky needs to be set as background for this to be
|
||||
enabled).
|
||||
|
||||
.. image:: img/environment_ambient.png
|
||||
![](img/environment_ambient.png)
|
||||
|
||||
When a *Sky* is set as background, it's possible to blend between ambient color
|
||||
and sky using the **Sky Contribution** setting (this value is 1.0 by default for
|
||||
@ -92,7 +92,7 @@ convenience, so only the sky affects objects).
|
||||
|
||||
Here is a comparison of how different ambient light affects a scene:
|
||||
|
||||
.. image:: img/environment_ambient2.png
|
||||
![](img/environment_ambient2.png)
|
||||
|
||||
Finally, there is an **Energy** setting, which is a multiplier. It's useful when
|
||||
working with HDR.
|
||||
@ -104,7 +104,7 @@ ambient light from ReflectionProbe or GIProbe, which will more faithfully simula
|
||||
how indirect light propagates. Below is a comparison, in terms of quality, between using a
|
||||
flat ambient color and a GIProbe:
|
||||
|
||||
.. image:: img/environment_ambient_comparison.png
|
||||
![](img/environment_ambient_comparison.png)
|
||||
|
||||
Using one of the methods described above, objects get constant ambient lighting
|
||||
replaced by ambient light from the probes.
|
||||
@ -119,7 +119,7 @@ There are two kinds of fog in Godot:
|
||||
- **Depth Fog:** This one is applied based on the distance from the camera.
|
||||
- **Height Fog:** This one is applied to any objects below (or above) a certain height, regardless of the distance from the camera.
|
||||
|
||||
.. image:: img/environment_fog_depth_height.png
|
||||
![](img/environment_fog_depth_height.png)
|
||||
|
||||
Both of these fog types can have their curve tweaked, making their transition more or less sharp.
|
||||
|
||||
@ -132,7 +132,7 @@ will be changed, simulating the sunlight passing through the fog.
|
||||
The second is **Transmit Enabled** which simulates more realistic light transmittance.
|
||||
In practice, it makes light stand out more across the fog.
|
||||
|
||||
.. image:: img/environment_fog_transmission.png
|
||||
![](img/environment_fog_transmission.png)
|
||||
|
||||
Tonemap
|
||||
^^^^^^^
|
||||
@ -187,7 +187,7 @@ interior areas with low light and outdoors. Auto exposure simulates the camera
|
||||
(or eye) in an effort to adapt between light and dark locations and their
|
||||
different amounts of light.
|
||||
|
||||
.. image:: img/environment_hdr_autoexp.gif
|
||||
![](img/environment_hdr_autoexp.gif)
|
||||
|
||||
The simplest way to use auto exposure is to make sure outdoor lights (or other
|
||||
strong lights) have energy beyond 1.0. This is done by tweaking their **Energy**
|
||||
@ -199,12 +199,12 @@ By combining Auto Exposure with *Glow* post processing (more on that below),
|
||||
pixels that go over the tonemap **White** will bleed to the glow buffer,
|
||||
creating the typical bloom effect in photography.
|
||||
|
||||
.. image:: img/environment_hdr_bloom.png
|
||||
![](img/environment_hdr_bloom.png)
|
||||
|
||||
The user-controllable values in the Auto Exposure section come with sensible
|
||||
defaults, but you can still tweak them:
|
||||
|
||||
.. image:: img/environment_hdr.png
|
||||
![](img/environment_hdr.png)
|
||||
|
||||
- **Scale:** Value to scale the lighting. Brighter values produce brighter images, smaller ones produce darker ones.
|
||||
- **Min Luma:** Minimum luminance that auto exposure will aim to adjust for. Luminance is the average of the light in all the pixels of the screen.
|
||||
@ -227,7 +227,7 @@ GIProbe), they may not provide enough detail for all situations. Scenarios
|
||||
where Screen Space Reflections make the most sense are when objects are in
|
||||
contact with each other (object over floor, over a table, floating on water, etc).
|
||||
|
||||
.. image:: img/environment_ssr.png
|
||||
![](img/environment_ssr.png)
|
||||
|
||||
The other advantage (even if only enabled to a minimum), is that it works in real-time
|
||||
(while the other types of reflections are pre-computed). This can be used to
|
||||
@ -263,7 +263,7 @@ This can be simulated with Screen Space Ambient Occlusion. As you can see in the
|
||||
image below, its purpose is to make sure concave areas are darker, simulating
|
||||
a narrower path for the light to enter:
|
||||
|
||||
.. image:: img/environment_ssao.png
|
||||
![](img/environment_ssao.png)
|
||||
|
||||
It is a common mistake to enable this effect, turn on a light, and not be able to
|
||||
appreciate it. This is because SSAO only acts on *ambient* light, not direct light.
|
||||
@ -274,11 +274,11 @@ the **Light Affect** parameter (even though this is not correct, some artists li
|
||||
|
||||
SSAO looks best when combined with a real source of indirect light, like GIProbe:
|
||||
|
||||
.. image:: img/environment_ssao2.png
|
||||
![](img/environment_ssao2.png)
|
||||
|
||||
Tweaking SSAO is possible with several parameters:
|
||||
|
||||
.. image:: img/environment_ssao_parameters.png
|
||||
![](img/environment_ssao_parameters.png)
|
||||
|
||||
- **Radius/Intensity:** To control the radius or intensity of the occlusion, these two parameters are available. Radius is in world (Metric) units.
|
||||
- **Radius2/Intensity2:** A Secondary radius/intensity can be used. Combining a large and a small radius AO generally works well.
|
||||
@ -296,7 +296,7 @@ This effect simulates focal distance on high end cameras. It blurs objects behin
|
||||
a given range. It has an initial **Distance** with a **Transition** region
|
||||
(in world units):
|
||||
|
||||
.. image:: img/environment_dof_far.png
|
||||
![](img/environment_dof_far.png)
|
||||
|
||||
The **Amount** parameter controls the amount of blur. For larger blurs, tweaking
|
||||
the **Quality** may be needed in order to avoid artifacts.
|
||||
@ -308,7 +308,7 @@ This effect simulates focal distance on high end cameras. It blurs objects close
|
||||
to the camera (acts in the opposite direction as far blur).
|
||||
It has an initial **Distance** with a **Transition** region (in world units):
|
||||
|
||||
.. image:: img/environment_dof_near.png
|
||||
![](img/environment_dof_near.png)
|
||||
|
||||
The **Amount** parameter controls the amount of blur. For larger blurs, tweaking
|
||||
the **Quality** may be needed in order to avoid artifacts.
|
||||
@ -316,7 +316,7 @@ the **Quality** may be needed in order to avoid artifacts.
|
||||
It is common to use both blurs together to focus the viewer's attention on a
|
||||
given object:
|
||||
|
||||
.. image:: img/environment_mixed_blur.png
|
||||
![](img/environment_mixed_blur.png)
|
||||
|
||||
Glow
|
||||
^^^^
|
||||
@ -325,18 +325,18 @@ In photography and film, when light amount exceeds the maximum supported by the
|
||||
media (be it analog or digital), it generally bleeds outwards to darker regions
|
||||
of the image. This is simulated in Godot with the **Glow** effect.
|
||||
|
||||
.. image:: img/environment_glow1.png
|
||||
![](img/environment_glow1.png)
|
||||
|
||||
By default, even if the effect is enabled, it will be weak or invisible. One of
|
||||
two conditions need to happen for it to actually show:
|
||||
|
||||
- 1) The light in a pixel surpasses the **HDR Threshold** (where 0 is all light surpasses it, and 1.0 is light over the tonemapper **White** value). Normally, this value is expected to be at 1.0, but it can be lowered to allow more light to bleed. There is also an extra parameter, **HDR Scale**, that allows scaling (making brighter or darker) the light surpassing the threshold.
|
||||
|
||||
.. image:: img/environment_glow_threshold.png
|
||||
![](img/environment_glow_threshold.png)
|
||||
|
||||
- 2) The Bloom effect has a value set greater than 0. As it increases, it sends the whole screen to the glow processor at higher amounts.
|
||||
|
||||
.. image:: img/environment_glow_bloom.png
|
||||
![](img/environment_glow_bloom.png)
|
||||
|
||||
Both will cause the light to start bleeding out of the brighter areas.
|
||||
|
||||
@ -356,19 +356,19 @@ To change the glow effect size and shape, Godot provides **Levels**. Smaller
|
||||
levels are strong glows that appear around objects, while large levels are hazy
|
||||
glows covering the whole screen:
|
||||
|
||||
.. image:: img/environment_glow_layers.png
|
||||
![](img/environment_glow_layers.png)
|
||||
|
||||
The real strength of this system, though, is to combine levels to create more
|
||||
interesting glow patterns:
|
||||
|
||||
.. image:: img/environment_glow_layers2.png
|
||||
![](img/environment_glow_layers2.png)
|
||||
|
||||
Finally, as the highest layers are created by stretching small blurred images,
|
||||
it is possible that some blockiness may be visible. Enabling **Bicubic Upscaling**
|
||||
gets rids of it, at a minimal performance cost.
|
||||
*Note that this is effective only when using the GLES3 backend.*
|
||||
|
||||
.. image:: img/environment_glow_bicubic.png
|
||||
![](img/environment_glow_bicubic.png)
|
||||
|
||||
Adjustments
|
||||
^^^^^^^^^^^
|
||||
@ -376,18 +376,18 @@ Adjustments
|
||||
At the end of processing, Godot offers the possibility to do some standard
|
||||
image adjustments.
|
||||
|
||||
.. image:: img/environment_adjustments.png
|
||||
![](img/environment_adjustments.png)
|
||||
|
||||
The first one is being able to change the typical Brightness, Contrast,
|
||||
and Saturation:
|
||||
|
||||
.. image:: img/environment_adjustments_bcs.png
|
||||
![](img/environment_adjustments_bcs.png)
|
||||
|
||||
The second is by supplying a color correction gradient. A regular black to
|
||||
white gradient like the following one will produce no effect:
|
||||
|
||||
.. image:: img/environment_adjusments_default_gradient.png
|
||||
![](img/environment_adjusments_default_gradient.png)
|
||||
|
||||
But creating custom ones will allow to map each channel to a different color:
|
||||
|
||||
.. image:: img/environment_adjusments_custom_gradient.png
|
||||
![](img/environment_adjusments_custom_gradient.png)
|
||||
|
@ -38,18 +38,18 @@ Setting up
|
||||
Just like a `ReflectionProbe`, simply set up the `GIProbe` by wrapping it around
|
||||
the geometry that will be affected.
|
||||
|
||||
.. image:: img/giprobe_wrap.png
|
||||
![](img/giprobe_wrap.png)
|
||||
|
||||
Afterwards, make sure to enable the **Use In Baked Light** property on the geometry instances
|
||||
in the inspector. This is required for `GIProbe` to recognize objects,
|
||||
otherwise they will be ignored:
|
||||
|
||||
.. image:: img/giprobe_bake_property.png
|
||||
![](img/giprobe_bake_property.png)
|
||||
|
||||
Once the geometry is set up, push the Bake button that appears on the 3D editor
|
||||
toolbar to begin the pre-baking process:
|
||||
|
||||
.. image:: img/giprobe_bake.png
|
||||
![](img/giprobe_bake.png)
|
||||
|
||||
.. warning::
|
||||
|
||||
@ -66,16 +66,16 @@ Lights need to be added to the scene to have an effect.
|
||||
The effect of indirect light can be viewed quickly (it is recommended you turn
|
||||
off all ambient/sky lighting to tweak this, though, as shown below):
|
||||
|
||||
.. image:: img/giprobe_indirect.png
|
||||
![](img/giprobe_indirect.png)
|
||||
|
||||
In some situations, though, indirect light may be too weak. Lights have an
|
||||
indirect multiplier to tweak this:
|
||||
|
||||
.. image:: img/giprobe_light_indirect.png
|
||||
![](img/giprobe_light_indirect.png)
|
||||
|
||||
And, as `GIProbe` lighting updates in real-time, this effect is immediate:
|
||||
|
||||
.. image:: img/giprobe_indirect_energy_result.png
|
||||
![](img/giprobe_indirect_energy_result.png)
|
||||
|
||||
Reflections
|
||||
-----------
|
||||
@ -84,12 +84,12 @@ For very metallic materials with low roughness, it's possible to appreciate
|
||||
voxel reflections. Keep in mind that these have far less detail than Reflection
|
||||
Probes or Screen Space Reflections, but fully reflect volumetrically.
|
||||
|
||||
.. image:: img/giprobe_voxel_reflections.png
|
||||
![](img/giprobe_voxel_reflections.png)
|
||||
|
||||
`GIProbe`\ s can be easily mixed with Reflection Probes and Screen Space Reflections,
|
||||
as a full 3-stage fallback-chain. This allows to have precise reflections where needed:
|
||||
|
||||
.. image:: img/giprobe_ref_blending.png
|
||||
![](img/giprobe_ref_blending.png)
|
||||
|
||||
Interior vs exterior
|
||||
--------------------
|
||||
@ -97,12 +97,12 @@ Interior vs exterior
|
||||
GI Probes normally allow mixing with lighting from the sky. This can be disabled
|
||||
when turning on the *Interior* setting.
|
||||
|
||||
.. image:: img/giprobe_interior_setting.png
|
||||
![](img/giprobe_interior_setting.png)
|
||||
|
||||
The difference becomes clear in the image below, where light from the sky goes
|
||||
from spreading inside to being ignored.
|
||||
|
||||
.. image:: img/giprobe_interior.png
|
||||
![](img/giprobe_interior.png)
|
||||
|
||||
As complex buildings may mix interiors with exteriors, combining GIProbes
|
||||
for both parts works well.
|
||||
@ -112,7 +112,7 @@ Tweaking
|
||||
|
||||
GI Probes support a few parameters for tweaking:
|
||||
|
||||
.. image:: img/giprobe_tweaking.png
|
||||
![](img/giprobe_tweaking.png)
|
||||
|
||||
- **Subdiv** Subdivision used for the probe. The default (128) is generally good for small- to medium-sized areas. Bigger subdivisions use more memory.
|
||||
- **Extents** Size of the probe. Can be tweaked from the gizmo.
|
||||
@ -131,4 +131,4 @@ Quality
|
||||
`GIProbe`\ s are quite demanding. It is possible to use lower quality voxel cone
|
||||
tracing in exchange for more performance.
|
||||
|
||||
.. image:: img/giprobe_quality.png
|
||||
![](img/giprobe_quality.png)
|
||||
|
@ -62,7 +62,7 @@ However, Godot currently only supports sRGB displays.
|
||||
The sRGB standard is based around the nonlinear relationship between the current
|
||||
to light output of common desktop computing CRT displays.
|
||||
|
||||
.. image:: img/hdr_gamma.png
|
||||
![](img/hdr_gamma.png)
|
||||
|
||||
The mathematics of a scene-referred model require that we multiply the scene by
|
||||
different values to adjust the intensities and exposure to different
|
||||
|
@ -24,7 +24,7 @@ Spatial node
|
||||
Following this reasoning, the 3D engine uses the `Spatial`
|
||||
node for everything 3D.
|
||||
|
||||
.. image:: img/tuto_3d1.png
|
||||
![](img/tuto_3d1.png)
|
||||
|
||||
Spatial nodes have a local transform, which is relative to the parent
|
||||
node (as long as the parent node is also of **or inherits from** the type
|
||||
@ -33,7 +33,7 @@ Spatial). This transform can be accessed as a 4×3
|
||||
members representing location, Euler rotation (X, Y and Z angles) and
|
||||
scale.
|
||||
|
||||
.. image:: img/tuto_3d2.png
|
||||
![](img/tuto_3d2.png)
|
||||
|
||||
3D content
|
||||
~~~~~~~~~~
|
||||
@ -113,14 +113,14 @@ Editing 3D scenes is done in the 3D tab. This tab can be selected
|
||||
manually, but it will be automatically enabled when a Spatial node is
|
||||
selected.
|
||||
|
||||
.. image:: img/tuto_3d3.png
|
||||
![](img/tuto_3d3.png)
|
||||
|
||||
Default 3D scene navigation controls are similar to Blender (aiming to
|
||||
have some sort of consistency in the free software pipeline..), but
|
||||
options are included to customize mouse buttons and behavior to be
|
||||
similar to other tools in the Editor Settings:
|
||||
|
||||
.. image:: img/tuto_3d4.png
|
||||
![](img/tuto_3d4.png)
|
||||
|
||||
Coordinate system
|
||||
-----------------
|
||||
@ -155,7 +155,7 @@ respectively. This convention applies to the grid and other gizmos too
|
||||
(and also to the shader language, ordering of components for
|
||||
Vector3, Color, etc.).
|
||||
|
||||
.. image:: img/tuto_3d5.png
|
||||
![](img/tuto_3d5.png)
|
||||
|
||||
Some useful keybindings:
|
||||
|
||||
@ -168,22 +168,22 @@ View menu
|
||||
|
||||
The view options are controlled by the "View" menu in the viewport's toolbar.
|
||||
|
||||
.. image:: img/tuto_3d6.png
|
||||
![](img/tuto_3d6.png)
|
||||
|
||||
You can hide the gizmos in the 3D view of the editor through this menu:
|
||||
|
||||
.. image:: img/tuto_3d6_1.png
|
||||
![](img/tuto_3d6_1.png)
|
||||
|
||||
To hide a specific type of gizmos, you can toggle them off in the "View" menu.
|
||||
|
||||
.. image:: img/tuto_3d6_2.png
|
||||
![](img/tuto_3d6_2.png)
|
||||
|
||||
Default environment
|
||||
-------------------
|
||||
|
||||
When created from the Project Manager, the 3D environment has a default sky.
|
||||
|
||||
.. image:: img/tuto_3d8.png
|
||||
![](img/tuto_3d8.png)
|
||||
|
||||
Given how physically based rendering works, it is advised to always try to
|
||||
work with a default environment in order to provide indirect and reflected
|
||||
@ -197,7 +197,7 @@ displayed unless a `Camera` is
|
||||
also added to the scene. Cameras can work in either orthogonal or
|
||||
perspective projections:
|
||||
|
||||
.. image:: img/tuto_3d10.png
|
||||
![](img/tuto_3d10.png)
|
||||
|
||||
Cameras are associated with (and only display to) a parent or grandparent
|
||||
viewport. Since the root of the scene tree is a viewport, cameras will
|
||||
@ -205,7 +205,7 @@ display on it by default, but if sub-viewports (either as render target
|
||||
or picture-in-picture) are desired, they need their own children cameras
|
||||
to display.
|
||||
|
||||
.. image:: img/tuto_3d11.png
|
||||
![](img/tuto_3d11.png)
|
||||
|
||||
When dealing with multiple cameras, the following rules are enforced for
|
||||
each viewport:
|
||||
|
@ -26,7 +26,7 @@ There are three types of light nodes: `Directional light`_,
|
||||
`Omni light`_ and `Spot light`_. Let's take a look at the common
|
||||
parameters for lights:
|
||||
|
||||
.. image:: img/light_params.png
|
||||
![](img/light_params.png)
|
||||
|
||||
Each one has a specific function:
|
||||
|
||||
@ -57,11 +57,11 @@ There is a list of generic shadow parameters, each also has a specific function:
|
||||
Below is an image of what tweaking bias looks like. Default values work for most
|
||||
cases, but in general it depends on the size and complexity of geometry.
|
||||
|
||||
.. image:: img/shadow_bias.png
|
||||
![](img/shadow_bias.png)
|
||||
|
||||
Finally, if gaps can't be solved, the **Contact** option can help (at a performance cost):
|
||||
|
||||
.. image:: img/shadow_contact.png
|
||||
![](img/shadow_contact.png)
|
||||
|
||||
Any sort of bias issues can always be fixed by increasing the shadow map resolution,
|
||||
although that may lead to decreased performance.
|
||||
@ -99,7 +99,7 @@ covering the whole scene. The directional light node is represented by a big arr
|
||||
indicates the direction of the light rays. However, the position of the node
|
||||
does not affect the lighting at all and can be anywhere.
|
||||
|
||||
.. image:: img/light_directional.png
|
||||
![](img/light_directional.png)
|
||||
|
||||
Every face whose front-side is hit by the light rays is lit, while the others stay dark. Most light types
|
||||
have specific parameters, but directional lights are pretty simple in nature, so they don't.
|
||||
@ -111,20 +111,20 @@ To compute shadow maps, the scene is rendered (only depth) from an orthogonal po
|
||||
the whole scene (or up to the max distance). There is, however, a problem with this approach because objects
|
||||
closer to the camera receive blocky shadows.
|
||||
|
||||
.. image:: img/shadow_blocky.png
|
||||
![](img/shadow_blocky.png)
|
||||
|
||||
To fix this, a technique named "Parallel Split Shadow Maps" (or PSSM) is used. This splits the view frustum in 2 or 4 areas. Each
|
||||
area gets its own shadow map. This allows small areas close to the viewer to have the same shadow resolution as a huge, far-away area.
|
||||
|
||||
.. image:: img/pssm_explained.png
|
||||
![](img/pssm_explained.png)
|
||||
|
||||
With this, shadows become more detailed:
|
||||
|
||||
.. image:: img/shadow_pssm.png
|
||||
![](img/shadow_pssm.png)
|
||||
|
||||
To control PSSM, a number of parameters are exposed:
|
||||
|
||||
.. image:: img/directional_shadow_params.png
|
||||
![](img/directional_shadow_params.png)
|
||||
|
||||
Each split distance is controlled relative to the camera far (or shadow
|
||||
**Max Distance** if greater than zero), so *0.0* is the eye position and *1.0*
|
||||
@ -139,13 +139,13 @@ Sometimes, the transition between a split and the next can look bad. To fix this
|
||||
the **"Blend Splits"** option can be turned on, which sacrifices detail in exchange
|
||||
for smoother transitions:
|
||||
|
||||
.. image:: img/blend_splits.png
|
||||
![](img/blend_splits.png)
|
||||
|
||||
The **"Normal Bias"** parameter can be used to fix special cases of self shadowing
|
||||
when objects are perpendicular to the light. The only downside is that it makes
|
||||
the shadow a bit thinner.
|
||||
|
||||
.. image:: img/normal_bias.png
|
||||
![](img/normal_bias.png)
|
||||
|
||||
The **"Bias Split Scale"** parameter can control extra bias for the splits that
|
||||
are far away. If self shadowing occurs only on the splits far away, this value can fix them.
|
||||
@ -159,7 +159,7 @@ Just experiment which setting works better for your scene.
|
||||
|
||||
Shadowmap size for directional lights can be changed in Project Settings -> Rendering -> Quality:
|
||||
|
||||
.. image:: img/project_setting_shadow.png
|
||||
![](img/project_setting_shadow.png)
|
||||
|
||||
Increasing it can solve bias problems, but decrease performance. Shadow mapping is an art of tweaking.
|
||||
|
||||
@ -169,18 +169,18 @@ Omni light
|
||||
Omni light is a point source that emits light spherically in all directions up to a given
|
||||
radius.
|
||||
|
||||
.. image:: img/light_omni.png
|
||||
![](img/light_omni.png)
|
||||
|
||||
In real life, light attenuation is an inverse function, which means omni lights don't have a radius.
|
||||
This is a problem because it means computing several omni lights would become demanding.
|
||||
|
||||
To solve this, a *Range* is introduced together with an attenuation function.
|
||||
|
||||
.. image:: img/light_omni_params.png
|
||||
![](img/light_omni_params.png)
|
||||
|
||||
These two parameters allow tweaking how this works visually in order to find aesthetically pleasing results.
|
||||
|
||||
.. image:: img/light_attenuation.png
|
||||
![](img/light_attenuation.png)
|
||||
|
||||
|
||||
Omni shadow mapping
|
||||
@ -193,7 +193,7 @@ Omni Shadows can be rendered as either **"Dual Paraboloid" or "Cube Mapped"**.
|
||||
The former renders quickly, but can cause deformations,
|
||||
while the later is more correct, but costlier.
|
||||
|
||||
.. image:: img/shadow_omni_dp_cm.png
|
||||
![](img/shadow_omni_dp_cm.png)
|
||||
|
||||
If the objects being rendered are mostly irregular, Dual Paraboloid is usually
|
||||
enough. In any case, as these shadows are cached in a shadow atlas (more on that at the end), it
|
||||
@ -207,7 +207,7 @@ Spot lights are similar to omni lights, except they emit light only into a cone
|
||||
car lights, reflectors, spots, etc. This type of light is also attenuated towards the
|
||||
opposite direction it points to.
|
||||
|
||||
.. image:: img/light_spot.png
|
||||
![](img/light_spot.png)
|
||||
|
||||
Spot lights share the same **Range** and **Attenuation** as **OmniLight**, and add two extra parameters:
|
||||
|
||||
@ -226,15 +226,15 @@ Shadow atlas
|
||||
Unlike Directional lights, which have their own shadow texture, Omni and Spot lights are assigned to slots of a shadow atlas.
|
||||
This atlas can be configured in Project Settings -> Rendering -> Quality -> Shadow Atlas.
|
||||
|
||||
.. image:: img/shadow_atlas.png
|
||||
![](img/shadow_atlas.png)
|
||||
|
||||
The resolution applies to the whole Shadow Atlas. This atlas is divided into four quadrants:
|
||||
|
||||
.. image:: img/shadow_quadrants.png
|
||||
![](img/shadow_quadrants.png)
|
||||
|
||||
Each quadrant can be subdivided to allocate any number of shadow maps; the following is the default subdivision:
|
||||
|
||||
.. image:: img/shadow_quadrants2.png
|
||||
![](img/shadow_quadrants2.png)
|
||||
|
||||
The allocation logic is simple. The biggest shadow map size (when no subdivision is used)
|
||||
represents a light the size of the screen (or bigger).
|
||||
@ -259,8 +259,8 @@ The filter quality of shadows can be tweaked. This can be found in
|
||||
Project Settings -> Rendering -> Quality -> Shadows.
|
||||
Godot supports no filter, PCF5 and PCF13.
|
||||
|
||||
.. image:: img/shadow_pcf1.png
|
||||
![](img/shadow_pcf1.png)
|
||||
|
||||
It affects the blockyness of the shadow outline:
|
||||
|
||||
.. image:: img/shadow_pcf2.png
|
||||
![](img/shadow_pcf2.png)
|
||||
|
@ -24,13 +24,13 @@ The sphere is one of the simplest and fastest occluders, and is easy to setup an
|
||||
|
||||
Once you have added an OccluderNode and chosen to add a new `OccluderShapeSphere` in the inspector, click the OccluderShapeSphere in the inspector to bring up the parameters.
|
||||
|
||||
.. image:: img/occluder_shape_sphere_inspector.png
|
||||
![](img/occluder_shape_sphere_inspector.png)
|
||||
|
||||
Unlike many Nodes, the `OccluderShapeSphere` can store multiple spheres in the same object. This is more efficient in the engine, and keeps your SceneTree clearer. You don't have to store all your spheres in one Occluder as it could become tricky to manage, but it is perfectly reasonable to add 10 or so spheres or more. They are very cheap, and often the more you place, the better the match you will get to your geometry.
|
||||
|
||||
In order to store multiple spheres, they are stored as an Array. If you click on the Array in the inspector, you can increase the size of the Array to add one.
|
||||
|
||||
.. image:: img/occluder_shape_sphere_terrain.png
|
||||
![](img/occluder_shape_sphere_terrain.png)
|
||||
|
||||
The sphere will appear as a small pink spherical object in the editor window. There are two handles on each sphere. The larger middle handle enables you to move the sphere around in the local space of the Occluder, and the small handle enables you to adjust the radius.
|
||||
|
||||
@ -56,18 +56,18 @@ Editing and details
|
||||
|
||||
Occluder polygons are edited as a list of points which define a *convex* polygon, on a single plane. In order to confine the polygon to a single plane, the points are defined in 2D space rather than 3D. The orientation, position and scale of the polygon is taken instead from the transform of the `Occluder` Node.
|
||||
|
||||
.. image:: img/occluder_shape_polygon_inspector.png
|
||||
![](img/occluder_shape_polygon_inspector.png)
|
||||
|
||||
If you create an Occluder and add to it a `OccluderShapePolygon` resource, by default it will create 4 starting points forming a rectangle. If you move the position and rotation of the Occluder Node you will see how the rectangle follows the node. When the Occluder is selected in the editor, handles will appear for each of the points. You can actually click and drag these handles, to match your polygon to the environment of your scene.
|
||||
|
||||
.. image:: img/occluder_shape_polygon.png
|
||||
![](img/occluder_shape_polygon.png)
|
||||
|
||||
You are not restricted to 4 points, you can add and remove points in the Inspector, but note that:
|
||||
|
||||
- The editor will automatically sanitize your points to form a convex polygon. If you drag a point into a position that would form a concave polygon, it will be ignored.
|
||||
- In general, the less edges (and thus points), the faster the polygon will work at runtime. A polygon with 6 edges will have to make twice the calculations of a polygon with 3 edges. In most cases 4 is a good number.
|
||||
|
||||
.. image:: img/occluder_shape_polygon2.png
|
||||
![](img/occluder_shape_polygon2.png)
|
||||
|
||||
Holes
|
||||
~~~~~
|
||||
@ -76,7 +76,7 @@ Real world game levels don't always have large continuous areas that should be o
|
||||
|
||||
In the inspector you will notice that as well as a set of points for the polygon, the polygon has a set of points for a single "hole". If you add 3 or 4 to your polygon, you will see they appear in the editor as smaller handles. You can drag these around just like the polygon handles, to form a convex hole.
|
||||
|
||||
.. image:: img/occluder_shape_polygon_hole.png
|
||||
![](img/occluder_shape_polygon_hole.png)
|
||||
|
||||
The hole can be totally within the polygon (such as a window), abutting the edge (like a door) or crossing the edge of the polygon completely, to make the occluder concave. The way the hole works is that the culling follows a simple rule:
|
||||
|
||||
|
@ -43,7 +43,7 @@ Gameplay callbacks have one more useful function. By default in Godot, animation
|
||||
|
||||
The engine's solution to this problem is the `VisibilityNotifier<class_VisibilityNotifier>` node, and its slightly easier to use variation, the `VisibilityEnabler<class_VisibilityEnabler>` node. VisibilityEnabler can be used to switch off animation and sleep physics when an object is outside the view frustum. You do this by simply placing a VisibilityEnabler node in your subscene (for e.g. a monster). It will do the rest. Consult the `VisibilityEnabler<class_VisibilityEnabler>` documentation for full details.
|
||||
|
||||
.. image:: img/visibility_enabler.png
|
||||
![](img/visibility_enabler.png)
|
||||
|
||||
What if the VisibilityEnabler could turn off objects when they were occlusion culled? Well it turns out VisibilityEnabler can. All you have to do is enable the **Gameplay Monitor** in the RoomManager and the rest happens automatically.
|
||||
|
||||
@ -54,13 +54,13 @@ RoomGroups
|
||||
|
||||
A `RoomGroup<class_RoomGroup>` is a special node which allows you to deal with a group of rooms at once, instead of having write code for them individually. This is especially useful in conjunction with gameplay callbacks. The most important use for RoomGroups is to delineate between "inside" and "outside" areas.
|
||||
|
||||
.. image:: img/roomgroups.png
|
||||
![](img/roomgroups.png)
|
||||
|
||||
For instance, when outside you may wish to use a `DirectionalLight<class_DirectionalLight>` to represent the sun. When the outside RoomGroup receives an `enter gameplay` callback, you can turn the light on, and you can turn it off when the RoomGroup exits gameplay. With the light off, performance will increase as there is no need to render it indoors.
|
||||
|
||||
This is an example of a simple RoomGroup script to turn on and off a DirectionalLight. Note that you can also use signals for callbacks (the choice is up to you):
|
||||
|
||||
.. image:: img/roomgroup_notification.png
|
||||
![](img/roomgroup_notification.png)
|
||||
|
||||
.. tip:: You can apply the same technique for switching on and off weather effects, skyboxes and much more.
|
||||
|
||||
@ -95,11 +95,11 @@ Internal room example
|
||||
|
||||
The tent is a simple room inside a terrain room (which contains the ground, the trees etc).
|
||||
|
||||
.. image:: img/tent.png
|
||||
![](img/tent.png)
|
||||
|
||||
.. note:: To use internal rooms for buildings, it is usually a good idea to split the *interior* mesh of the building from the *exterior*. The exterior can be placed in the outer room (so it can be seen from outside, but not from the inside), and the interior should be placed in the interior room (so it only visible inside, or through the portal).
|
||||
|
||||
.. image:: img/tent_terrain.png
|
||||
![](img/tent_terrain.png)
|
||||
|
||||
This is perfect for improving performance in open world games. Often your buildings can be scenes (including the rooms and portals) that can be reused. When viewed from the outside, interiors will mostly be culled, and when viewing from the inside other buildings and most of the outside will be culled. The same goes for other players and objects that are inside and outside the buildings.
|
||||
|
||||
@ -110,7 +110,7 @@ Internal room scenes
|
||||
|
||||
Let us look in detail at another practical example for an open world. We want to place houses (as internal rooms) on an island, but have each house as a self-contained scene containing both the interior *and* the external mesh of the house.
|
||||
|
||||
.. image:: img/house_scene.png
|
||||
![](img/house_scene.png)
|
||||
|
||||
We have created a Room node (which will become the internal room) into which we have placed the interior meshes. We have also created a Portal with no links (so autolinking will be used). The exterior mesh is *not* within the room. It will be autoplaced, and we are intending for it to be placed within the outer room.
|
||||
|
||||
@ -120,7 +120,7 @@ To get around this problem, there is a special setting to enable you to express
|
||||
|
||||
However, if we set this autoplace priority to `-1` for example, the autoplace will always choose a `-1` priority room (if one is present at that location). So if we set the outer room priority to `-1`, it will always place our exterior into our "outside" room.
|
||||
|
||||
.. image:: img/autoplace_priority.png
|
||||
![](img/autoplace_priority.png)
|
||||
|
||||
This gives us a helpful extra bit of control for these kinds of situations, and makes the entire system much more flexible.
|
||||
|
||||
@ -128,6 +128,6 @@ This gives us a helpful extra bit of control for these kinds of situations, and
|
||||
|
||||
The final scene looks something like this, with houses instanced wherever you want them on a giant outer room.
|
||||
|
||||
.. image:: img/island.png
|
||||
![](img/island.png)
|
||||
|
||||
The house exteriors will be placed in the outer room, and therefore can always be seen when looking from the outside. The interiors will only be rendered when a view into the entry portals is visible.
|
||||
|
@ -6,7 +6,7 @@ Example SceneTree
|
||||
|
||||
Putting all the ideas together, here is an example scene tree:
|
||||
|
||||
.. image:: img/example_scenetree.png
|
||||
![](img/example_scenetree.png)
|
||||
|
||||
- We have used a `RoomGroup<class_RoomGroup>` to denote an outside area.
|
||||
- The `MeshInstance<class_MeshInstance>`\ s inside the `Room<class_Room>`\ s are either `STATIC` or `DYNAMIC`.
|
||||
@ -77,7 +77,7 @@ Portals are defined by a combination of the transform of the portal node, and by
|
||||
|
||||
The default portal has 4 corners as shown in the inspector:
|
||||
|
||||
.. image:: img/portal_point_editing.png
|
||||
![](img/portal_point_editing.png)
|
||||
|
||||
You can edit these points in the gizmo or inspector to make a better match to the opening in your game level. It's generally better to keep the number of points as low as possible for the efficiency of the system. For example, it's better to risk rendering a little too much than to spend the time culling objects at 20 different edges.
|
||||
|
||||
@ -88,7 +88,7 @@ Room point editing
|
||||
|
||||
You also have the option to manually edit the points used to define the convex hull of a room. These points are not present by default. You would typically create them by pressing the **Generate Points** button in the editor toolbar when a room is selected. This will transfer the auto bound from the geometry (or manual `-bound` mesh) into the inspector. Once there are points in the inspector, they will be used and override any other method. So if you wish to revert your manual editing, delete all the room's points.
|
||||
|
||||
.. image:: img/room_point_editing.png
|
||||
![](img/room_point_editing.png)
|
||||
|
||||
Manually editing points can be useful in some situations, especially where the auto-bound doesn't *quite* get the right result you want. It is usually a good idea to use a lot of **Simplification** in the inspector for the Room before generating the points. Be aware though that by default, the **Simplification** value will be inherited from the RoomManager.
|
||||
|
||||
|
@ -11,20 +11,20 @@ Room Conversion
|
||||
|
||||
This conversion must take place every time you want to activate the system. It does not store the *room graph* in your project (for flexibility and to save memory). You can either trigger it by pressing the **Convert Rooms** button in the editor toolbar (which also has a keyboard shortcut) or by calling the `rooms_convert()` method in the RoomManager. The latter method will be what you use in-game. Note that for safety, best practice is to call `rooms_clear()` before unloading or changing levels.
|
||||
|
||||
.. image:: img/convert_rooms_button.png
|
||||
![](img/convert_rooms_button.png)
|
||||
|
||||
If you convert the level while the editor is running, the portal culling system will take over from the normal Godot frustum culling, potentially interfering with editor features. To get around this, you can turn portal culling on and off using either the **View Portal Culling** toggle in the **View** menu on the editor toolbar (which also has a keyboard shortcut) or the **Active** setting in the RoomManager node.
|
||||
|
||||
.. note:: To use the RoomManager, you have to tell it where the rooms are in your scene tree, or, more specifically, where the RoomList node is. This RoomList is the parent of your rooms - see below. If the RoomList is not set, conversion will fail, and you will see a warning dialog box.
|
||||
|
||||
.. image:: img/room_manager.png
|
||||
![](img/room_manager.png)
|
||||
|
||||
The RoomList
|
||||
^^^^^^^^^^^^
|
||||
|
||||
Before we create any rooms, we must first create a node to be the parent of all the static objects, rooms, roomgroups, and so on in our level. This node is referred to as the the `RoomList`.
|
||||
|
||||
.. image:: img/roomlist_node.png
|
||||
![](img/roomlist_node.png)
|
||||
|
||||
.. note:: The roomlist is **not** a special node type – it can just be a regular Spatial.
|
||||
|
||||
@ -51,7 +51,7 @@ Rooms are defined as convex volumes (or *convex hulls*) because it's trivial to
|
||||
|
||||
*A convex hull. The hull is defined as a series of planes facing outward. If a point is behind all the planes, it is within the hull.*
|
||||
|
||||
.. image:: img/convex_hull.png
|
||||
![](img/convex_hull.png)
|
||||
|
||||
Why non-overlapping?
|
||||
^^^^^^^^^^^^^^^^^^^^
|
||||
@ -60,7 +60,7 @@ If two rooms overlap, and a camera or player is in this overlapping zone, then t
|
||||
|
||||
If you accidentally create overlapping rooms, the editor will warn you when you convert the rooms, indicating any overlapping zones in red.
|
||||
|
||||
.. image:: img/room_overlap.png
|
||||
![](img/room_overlap.png)
|
||||
|
||||
The system does attempt to cope with overlapping rooms as best as possible by making the current room *"sticky"*. Each object remembers which room it was in during the previous frame and stays within it as long as it does not move outside the convex hull room bound. This can result in some hysteresis in these overlapping zones.
|
||||
|
||||
@ -86,7 +86,7 @@ The automatic method is used whenever a manual bound is not supplied.
|
||||
|
||||
*A simple pair of rooms. The portal margin is shown with translucent red, and the room hulls are shown with green wireframe.*
|
||||
|
||||
.. image:: img/simple_room.png
|
||||
![](img/simple_room.png)
|
||||
|
||||
Portals
|
||||
~~~~~~~
|
||||
@ -99,7 +99,7 @@ To save editing effort, **only one Portal is required between each pair of Rooms
|
||||
|
||||
You should therefore place a portal in only one of each pair of neighbouring rooms - this is the portal's *"source room"*. Generally it doesn't matter which you choose as the source room. The portal normal (the arrow in the gizmo) should face *outward* from the source room.
|
||||
|
||||
.. image:: img/portal_inspector.png
|
||||
![](img/portal_inspector.png)
|
||||
|
||||
Do not be confused by the arrow. Although the arrow shows which direction the portal faces, most portals will be *two-way*, and can be seen through from both directions. The arrow is more important for ensuring that the portal links to the correct neighbouring room.
|
||||
|
||||
@ -118,7 +118,7 @@ Trying it out
|
||||
|
||||
By now you should be able to create a couple of rooms, add some nodes such as MeshInstances within the rooms, and add a portal between the rooms. Try converting the rooms in the editor and see if you can now view the objects in neighbouring rooms through the portal.
|
||||
|
||||
.. image:: img/simple_scenetree.png
|
||||
![](img/simple_scenetree.png)
|
||||
|
||||
You have now mastered the basic principles of the system.
|
||||
|
||||
|
@ -13,7 +13,7 @@ This tutorial will introduce you to building a "Hello World" room system with tw
|
||||
Step 1
|
||||
~~~~~~
|
||||
|
||||
.. image:: tutorial_simple/img/tutorial_simple_1.png
|
||||
![](tutorial_simple/img/tutorial_simple_1.png)
|
||||
|
||||
- Create a new project.
|
||||
- Add a `Spatial<class_Spatial>` as the scene root (on the screenshot, it's called "Root").
|
||||
@ -28,7 +28,7 @@ Step 1
|
||||
Step 2
|
||||
~~~~~~
|
||||
|
||||
.. image:: tutorial_simple/img/tutorial_simple_2.png
|
||||
![](tutorial_simple/img/tutorial_simple_2.png)
|
||||
|
||||
- Now we need to create the other room.
|
||||
- You can do this simply by duplicating the first room (select the `Kitchen` node, right click and choose **Duplicate**).
|
||||
@ -38,7 +38,7 @@ Step 2
|
||||
Step 3
|
||||
~~~~~~
|
||||
|
||||
.. image:: tutorial_simple/img/tutorial_simple_3.png
|
||||
![](tutorial_simple/img/tutorial_simple_3.png)
|
||||
|
||||
- Next, we will add a portal between the two rooms.
|
||||
- Create a new `Portal<class_Portal>` in the kitchen.
|
||||
@ -48,7 +48,7 @@ Step 3
|
||||
Step 4
|
||||
~~~~~~
|
||||
|
||||
.. image:: tutorial_simple/img/tutorial_simple_4.png
|
||||
![](tutorial_simple/img/tutorial_simple_4.png)
|
||||
|
||||
- To make things more exciting, we want to add a few more boxes to the rooms.
|
||||
- Placing these boxes as children or grandchildren of the room nodes explicitly tells the system which room the objects should be in. However, we can also create these objects *outside* the rooms. Provided they are in the RoomList branch, the system will attempt to automatically place them in the correct room at runtime.
|
||||
@ -59,7 +59,7 @@ Step 4
|
||||
Step 5
|
||||
~~~~~~
|
||||
|
||||
.. image:: tutorial_simple/img/tutorial_simple_5.png
|
||||
![](tutorial_simple/img/tutorial_simple_5.png)
|
||||
|
||||
- Next comes a crucial stage. We must let the RoomManager know where the rooms are!
|
||||
- Select the RoomManager and look in the Inspector window in the **Paths** section.
|
||||
@ -68,7 +68,7 @@ Step 5
|
||||
Step 6
|
||||
~~~~~~
|
||||
|
||||
.. image:: tutorial_simple/img/tutorial_simple_6.png
|
||||
![](tutorial_simple/img/tutorial_simple_6.png)
|
||||
|
||||
- Make sure you have saved your project before this next step. It is always a good idea to save and make a backup before converting.
|
||||
- Select the RoomManager, and you will see a button in the toolbar at the top of the 3d editor viewport called **Convert Rooms**. Press this button.
|
||||
|
@ -8,7 +8,7 @@ Portal mode
|
||||
|
||||
If you look in the inspector, every VisualInstance in Godot is derived from a `CullInstance<class_CullInstance>`, where you can set a `PortalMode`. This determines how objects will behave in the portal system.
|
||||
|
||||
.. image:: img/cull_instance.png
|
||||
![](img/cull_instance.png)
|
||||
|
||||
STATIC
|
||||
^^^^^^
|
||||
@ -45,7 +45,7 @@ Autoplace
|
||||
|
||||
However, for ease of use, it is also possible to place `STATIC` and `DYNAMIC` objects *outside* the rooms in the scene tree, but within the RoomList branch. The system will attempt to **autoplace** the objects into the appropriate room. This works in most cases but if in doubt, use the explicit approach. The explicit approach is especially needed when dealing with internal rooms, which have some restrictions for sprawling objects.
|
||||
|
||||
.. image:: img/freeform.png
|
||||
![](img/freeform.png)
|
||||
|
||||
Note that if you place `STATIC` and `DYNAMIC` objects outside of rooms, they will not contribute to the room bound. If you are using the room geometry to derive the bound, tables and chairs can be placed outside the room. However, walls and floors should be explicitly within the Room's branch of the scene tree to ensure the bound is correct.
|
||||
|
||||
|
@ -22,7 +22,7 @@ Setting up
|
||||
|
||||
Create a ReflectionProbe node and wrap it around the area where you want to have reflections:
|
||||
|
||||
.. image:: img/refprobe_setup.png
|
||||
![](img/refprobe_setup.png)
|
||||
|
||||
This should result in immediate local reflections. If you are using a Sky texture,
|
||||
reflections are by default blended with it.
|
||||
@ -30,13 +30,13 @@ reflections are by default blended with it.
|
||||
By default, on interiors, reflections may appear not to have much consistence.
|
||||
In this scenario, make sure to tick the *"Box Correct"* property.
|
||||
|
||||
.. image:: img/refprobe_box_property.png
|
||||
![](img/refprobe_box_property.png)
|
||||
|
||||
|
||||
This setting changes the reflection from an infinite skybox to reflecting
|
||||
a box the size of the probe:
|
||||
|
||||
.. image:: img/refprobe_boxcorrect.png
|
||||
![](img/refprobe_boxcorrect.png)
|
||||
|
||||
Adjusting the box walls may help improve the reflection a bit, but it will
|
||||
always look best in box shaped rooms.
|
||||
@ -45,21 +45,21 @@ The probe captures the surrounding from the center of the gizmo. If, for some
|
||||
reason, the room shape or contents occlude the center, it
|
||||
can be displaced to an empty place by moving the handles in the center:
|
||||
|
||||
.. image:: img/refprobe_center_gizmo.png
|
||||
![](img/refprobe_center_gizmo.png)
|
||||
|
||||
By default, shadow mapping is disabled when rendering probes (only in the
|
||||
rendered image inside the probe, not the actual scene). This is
|
||||
a simple way to save on performance and memory. If you want shadows in the probe,
|
||||
they can be toggled on/off with the *Enable Shadow* setting:
|
||||
|
||||
.. image:: img/refprobe_shadows.png
|
||||
![](img/refprobe_shadows.png)
|
||||
|
||||
Finally, keep in mind that you may not want the Reflection Probe to render some
|
||||
objects. A typical scenario is an enemy inside the room which will
|
||||
move around. To keep objects from being rendered in the reflections,
|
||||
use the *Cull Mask* setting:
|
||||
|
||||
.. image:: img/refprobe_cullmask.png
|
||||
![](img/refprobe_cullmask.png)
|
||||
|
||||
Interior vs exterior
|
||||
--------------------
|
||||
@ -68,7 +68,7 @@ If you are using reflection probes in an interior setting, it is recommended
|
||||
that the **Interior** property be enabled. This stops
|
||||
the probe from rendering the sky and also allows custom ambient lighting settings.
|
||||
|
||||
.. image:: img/refprobe_ambient.png
|
||||
![](img/refprobe_ambient.png)
|
||||
|
||||
When probes are set to **Interior**, custom constant ambient lighting can be
|
||||
specified per probe. Just choose a color and an energy.
|
||||
@ -82,7 +82,7 @@ Blending
|
||||
|
||||
Multiple reflection probes can be used, and Godot will blend them where they overlap using a smart algorithm:
|
||||
|
||||
.. image:: img/refprobe_blending.png
|
||||
![](img/refprobe_blending.png)
|
||||
|
||||
As you can see, this blending is never perfect (after all, these are
|
||||
box reflections, not real reflections), but these artifacts
|
||||
@ -94,7 +94,7 @@ Alternatively, Reflection Probes work well blended together with Screen Space
|
||||
Reflections to solve these problems. Combining them makes local reflections appear
|
||||
more faithful, while probes are only used as a fallback when no screen-space information is found:
|
||||
|
||||
.. image:: img/refprobe_ssr.png
|
||||
![](img/refprobe_ssr.png)
|
||||
|
||||
Finally, blending interior and exterior probes is the recommended approach when making
|
||||
levels that combine both interiors and exteriors. Near the door, a probe can
|
||||
@ -109,4 +109,4 @@ customized in Project Settings -> Quality -> Reflections
|
||||
|
||||
The default setting of Atlas Subdiv: 8 will allow up to 16 reflection probes in a scene. This value needs to be increased if you need more reflection probes.
|
||||
|
||||
.. image:: img/refprobe_atlas.png
|
||||
![](img/refprobe_atlas.png)
|
||||
|
@ -17,7 +17,7 @@ the *Material* property of the mesh. It can be added in the *Material* property
|
||||
the node using the mesh (such as a MeshInstance node), the *Material Override* property
|
||||
of the node using the mesh, and the *Material Overlay*.
|
||||
|
||||
.. image:: img/add_material.png
|
||||
![](img/add_material.png)
|
||||
|
||||
If you add a material to the mesh itself, every time that mesh is used it will have that
|
||||
material. If you add a material to the node using the mesh, the material will only be used
|
||||
@ -34,7 +34,7 @@ Flags
|
||||
|
||||
Spatial materials have many flags determining the general usage of a material.
|
||||
|
||||
.. image:: img/spatial_material1.png
|
||||
![](img/spatial_material1.png)
|
||||
|
||||
Transparent
|
||||
~~~~~~~~~~~
|
||||
@ -69,7 +69,7 @@ However, in some cases you might want to show just the albedo (color) and
|
||||
ignore the rest. Toggling this flag on will remove all shading and display
|
||||
pure, unlit color.
|
||||
|
||||
.. image:: img/spatial_material26.png
|
||||
![](img/spatial_material26.png)
|
||||
|
||||
Vertex Lighting
|
||||
~~~~~~~~~~~~~~~
|
||||
@ -85,7 +85,7 @@ cases.
|
||||
Additionally, on low-end or mobile devices, switching to vertex lighting
|
||||
can considerably increase rendering performance.
|
||||
|
||||
.. image:: img/spatial_material2.png
|
||||
![](img/spatial_material2.png)
|
||||
|
||||
Keep in mind that when vertex lighting is enabled, only directional lighting
|
||||
can produce shadows (for performance reasons).
|
||||
@ -101,7 +101,7 @@ Disabling this makes the most sense for drawing indicators in world space,
|
||||
and works very well with the *Render Priority* property of Material
|
||||
(see the bottom of this page).
|
||||
|
||||
.. image:: img/spatial_material3.png
|
||||
![](img/spatial_material3.png)
|
||||
|
||||
Use Point Size
|
||||
~~~~~~~~~~~~~~~
|
||||
@ -147,7 +147,7 @@ Vertex Color
|
||||
This setting allows choosing what is done by default to vertex colors that come
|
||||
from your 3D modelling application. By default, they are ignored.
|
||||
|
||||
.. image:: img/spatial_material4.png
|
||||
![](img/spatial_material4.png)
|
||||
|
||||
Use as Albedo
|
||||
~~~~~~~~~~~~~
|
||||
@ -166,7 +166,7 @@ Parameters
|
||||
`SpatialMaterial` also has several configurable parameters to tweak
|
||||
many aspects of the rendering:
|
||||
|
||||
.. image:: img/spatial_material5.png
|
||||
![](img/spatial_material5.png)
|
||||
|
||||
Diffuse Mode
|
||||
~~~~~~~~~~~~
|
||||
@ -186,7 +186,7 @@ the object. The default is *Burley*. Other modes are also available:
|
||||
ambient light settings or disable ambient light in the spatial material
|
||||
to achieve a better effect.
|
||||
|
||||
.. image:: img/spatial_material6.png
|
||||
![](img/spatial_material6.png)
|
||||
|
||||
Specular Mode
|
||||
~~~~~~~~~~~~~
|
||||
@ -201,7 +201,7 @@ represents the shape of a light source reflected in the object.
|
||||
* **Toon:** Creates a toon blob, which changes size depending on roughness.
|
||||
* **Disabled:** Sometimes the blob gets in the way. Begone!
|
||||
|
||||
.. image:: img/spatial_material7.png
|
||||
![](img/spatial_material7.png)
|
||||
|
||||
Blend Mode
|
||||
~~~~~~~~~~
|
||||
@ -215,7 +215,7 @@ other than *Mix* forces the object to go through the transparent pipeline.
|
||||
* **Sub:** Object is subtracted.
|
||||
* **Mul:** Object is multiplied.
|
||||
|
||||
.. image:: img/spatial_material8.png
|
||||
![](img/spatial_material8.png)
|
||||
|
||||
Cull Mode
|
||||
~~~~~~~~~
|
||||
@ -248,7 +248,7 @@ Specifies when depth rendering must take place.
|
||||
with the opaque parts, then transparency is drawn above.
|
||||
Use this option with transparent grass or tree foliage.
|
||||
|
||||
.. image:: img/material_depth_draw.png
|
||||
![](img/material_depth_draw.png)
|
||||
|
||||
Line Width
|
||||
~~~~~~~~~~
|
||||
@ -274,7 +274,7 @@ faces the camera:
|
||||
* **Particles:** Most suited for particle systems, because it allows
|
||||
specifying animation options.
|
||||
|
||||
.. image:: img/spatial_material9.png
|
||||
![](img/spatial_material9.png)
|
||||
|
||||
The above options are only enabled for Particle Billboard.
|
||||
|
||||
@ -288,12 +288,12 @@ Grow
|
||||
|
||||
Grows the object vertices in the direction pointed by their normals:
|
||||
|
||||
.. image:: img/spatial_material10.png
|
||||
![](img/spatial_material10.png)
|
||||
|
||||
This is commonly used to create cheap outlines. Add a second material pass,
|
||||
make it black and unshaded, reverse culling (Cull Front), and add some grow:
|
||||
|
||||
.. image:: img/spatial_material11.png
|
||||
![](img/spatial_material11.png)
|
||||
|
||||
|
||||
Use Alpha Scissor
|
||||
@ -302,7 +302,7 @@ Use Alpha Scissor
|
||||
When transparency other than `0` or `1` is not needed, it's possible to
|
||||
set a threshold to prevent the object from rendering semi-transparent pixels.
|
||||
|
||||
.. image:: img/spatial_material12.png
|
||||
![](img/spatial_material12.png)
|
||||
|
||||
This renders the object via the opaque pipeline, which is faster and allows it
|
||||
to use mid- and post-process effects such as SSAO, SSR, etc.
|
||||
@ -344,7 +344,7 @@ it unless you need to).
|
||||
The minimum internal reflectivity is `0.04`, so it's impossible to make a
|
||||
material completely unreflective, just like in real life.
|
||||
|
||||
.. image:: img/spatial_material13.png
|
||||
![](img/spatial_material13.png)
|
||||
|
||||
Roughness
|
||||
~~~~~~~~~
|
||||
@ -354,7 +354,7 @@ perfect mirror while a value of `1` completely blurs the reflection (simulating
|
||||
natural microsurfacing). Most common types of materials can be achieved with
|
||||
the right combination of *Metallic* and *Roughness*.
|
||||
|
||||
.. image:: img/spatial_material14.png
|
||||
![](img/spatial_material14.png)
|
||||
|
||||
Emission
|
||||
~~~~~~~~
|
||||
@ -364,7 +364,7 @@ does not include light surrounding geometry unless `doc_gi_probes` are used).
|
||||
This value is added to the resulting final image and is not affected by other
|
||||
lighting in the scene.
|
||||
|
||||
.. image:: img/spatial_material15.png
|
||||
![](img/spatial_material15.png)
|
||||
|
||||
Normal map
|
||||
~~~~~~~~~~
|
||||
@ -374,7 +374,7 @@ This does not modify geometry, only the incident angle for light. In Godot,
|
||||
only the red and green channels of normal maps are used for better compression
|
||||
and wider compatibility.
|
||||
|
||||
.. image:: img/spatial_material16.png
|
||||
![](img/spatial_material16.png)
|
||||
|
||||
.. note::
|
||||
|
||||
@ -395,7 +395,7 @@ emulates this with the *Rim* parameter. Unlike other rim lighting implementation
|
||||
which just use the emission channel, this one actually takes light into account
|
||||
(no light means no rim). This makes the effect considerably more believable.
|
||||
|
||||
.. image:: img/spatial_material17.png
|
||||
![](img/spatial_material17.png)
|
||||
|
||||
Rim size depends on roughness, and there is a special parameter to specify how
|
||||
it must be colored. If *Tint* is `0`, the color of the light is used for the
|
||||
@ -416,7 +416,7 @@ lighting or looking at a material a specific way to notice a difference.
|
||||
This can be seen in the image below where clearcoat is turned on in the
|
||||
right.
|
||||
|
||||
.. image:: img/clearcoat_comparison.png
|
||||
![](img/clearcoat_comparison.png)
|
||||
|
||||
.. note:: The effect will be more noticeable in Godot 4.
|
||||
|
||||
@ -429,7 +429,7 @@ This changes the shape of the specular blob and aligns it to tangent space.
|
||||
Anisotropy is commonly used with hair, or to make materials such as brushed
|
||||
aluminum more realistic. It works especially well when combined with flowmaps.
|
||||
|
||||
.. image:: img/spatial_material18.png
|
||||
![](img/spatial_material18.png)
|
||||
|
||||
Ambient Occlusion
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
@ -440,7 +440,7 @@ light by default). While it is possible to use Screen-Space Ambient Occlusion
|
||||
(SSAO) to generate ambient occlusion, nothing beats the quality of a well-baked
|
||||
AO map. It is recommended to bake ambient occlusion whenever possible.
|
||||
|
||||
.. image:: img/spatial_material19.png
|
||||
![](img/spatial_material19.png)
|
||||
|
||||
Depth
|
||||
~~~~~
|
||||
@ -453,7 +453,7 @@ added geometry, but an illusion of depth. It may not work for complex objects,
|
||||
but it produces a realistic depth effect for textures. For best results,
|
||||
*Depth* should be used together with normal mapping.
|
||||
|
||||
.. image:: img/spatial_material20.png
|
||||
![](img/spatial_material20.png)
|
||||
|
||||
Subsurface Scattering
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -464,7 +464,7 @@ This effect emulates light that penetrates an object's surface, is scattered,
|
||||
and then comes out. It is useful to create realistic skin, marble, colored
|
||||
liquids, etc.
|
||||
|
||||
.. image:: img/spatial_material21.png
|
||||
![](img/spatial_material21.png)
|
||||
|
||||
Transmission
|
||||
~~~~~~~~~~~~
|
||||
@ -473,7 +473,7 @@ This controls how much light from the lit side (visible to light) is transferred
|
||||
to the dark side (opposite from the light). This works well for thin objects
|
||||
such as plant leaves, grass, human ears, etc.
|
||||
|
||||
.. image:: img/spatial_material22.png
|
||||
![](img/spatial_material22.png)
|
||||
|
||||
Refraction
|
||||
~~~~~~~~~~~
|
||||
@ -484,7 +484,7 @@ When refraction is enabled, it supersedes alpha blending, and Godot attempts to
|
||||
fetch information from behind the object being rendered instead. This allows
|
||||
distorting the transparency in a way similar to refraction in real life.
|
||||
|
||||
.. image:: img/spatial_material23.png
|
||||
![](img/spatial_material23.png)
|
||||
|
||||
Detail
|
||||
~~~~~~
|
||||
@ -493,7 +493,7 @@ Godot allows using secondary albedo and normal maps to generate a detail
|
||||
texture, which can be blended in many ways. By combining this with secondary
|
||||
UV or triplanar modes, many interesting textures can be achieved.
|
||||
|
||||
.. image:: img/spatial_material24.png
|
||||
![](img/spatial_material24.png)
|
||||
|
||||
There are several settings that control how detail is used.
|
||||
|
||||
@ -545,7 +545,7 @@ performed in either world space or object space.
|
||||
In the image below, you can see how all primitives share the same material with
|
||||
world triplanar, so the brick texture continues smoothly between them.
|
||||
|
||||
.. image:: img/spatial_material25.png
|
||||
![](img/spatial_material25.png)
|
||||
|
||||
Proximity and distance fade
|
||||
----------------------------
|
||||
@ -559,7 +559,7 @@ given distance.
|
||||
Keep in mind enabling these enables alpha blending, so abusing them for an
|
||||
entire scene is usually not a good idea.
|
||||
|
||||
.. image:: img/spatial_material_proxfade.gif
|
||||
![](img/spatial_material_proxfade.gif)
|
||||
|
||||
Render priority
|
||||
---------------
|
||||
|
@ -31,7 +31,7 @@ To begin, you need a `MeshLibrary`, which is a collection
|
||||
of individual meshes that can be used in the gridmap. Open the "MeshLibrary_Source.tscn"
|
||||
scene to see an example of how to set up the mesh library.
|
||||
|
||||
.. image:: img/gridmap_meshlibrary1.png
|
||||
![](img/gridmap_meshlibrary1.png)
|
||||
|
||||
As you can see, this scene has a `Spatial` node as its root, and
|
||||
a number of `MeshInstance` node children.
|
||||
@ -46,14 +46,14 @@ You can manually assign a `StaticBody` and
|
||||
`CollisionShape` to each mesh. Alternatively, you can use the "Mesh" menu
|
||||
to automatically create the collision body based on the mesh data.
|
||||
|
||||
.. image:: img/gridmap_create_body.png
|
||||
![](img/gridmap_create_body.png)
|
||||
|
||||
Note that a "Convex" collision body will work better for simple meshes. For more
|
||||
complex shapes, select "Create Trimesh Static Body". Once each mesh has
|
||||
a physics body and collision shape assigned, your mesh library is ready to
|
||||
be used.
|
||||
|
||||
.. image:: img/gridmap_mesh_scene.png
|
||||
![](img/gridmap_mesh_scene.png)
|
||||
|
||||
|
||||
Materials
|
||||
@ -78,7 +78,7 @@ geometry nodes below and bake the NavigationMesh.
|
||||
With small grid cells it is often necessary to reduce the NavigationMesh properties
|
||||
for agent radius and region minimum size.
|
||||
|
||||
.. image:: img/meshlibrary_scene.png
|
||||
![](img/meshlibrary_scene.png)
|
||||
|
||||
Nodes below the NavigationMeshInstance are ignored for the MeshLibrary scene export, so
|
||||
additional nodes can be added as source geometry just for baking the navmesh.
|
||||
@ -94,7 +94,7 @@ Exporting the MeshLibrary
|
||||
To export the library, click on Scene -> Convert To.. -> MeshLibrary.., and save it
|
||||
as a resource.
|
||||
|
||||
.. image:: img/gridmap_export.png
|
||||
![](img/gridmap_export.png)
|
||||
|
||||
You can find an already exported MeshLibrary in the project named "MeshLibrary.tres".
|
||||
|
||||
@ -105,7 +105,7 @@ Create a new scene and add a GridMap node. Add the mesh library by dragging
|
||||
the resource file from the FileSystem dock and dropping it in the "Theme" property
|
||||
in the Inspector.
|
||||
|
||||
.. image:: img/gridmap_main.png
|
||||
![](img/gridmap_main.png)
|
||||
|
||||
The "Cell/Size" property should be set to the size of your meshes. You can leave
|
||||
it at the default value for the demo. Set the "Center Y" property to "Off".
|
||||
@ -117,18 +117,18 @@ and use Right-click.
|
||||
Click on the "GridMap" menu to see options and shortcuts. For example, pressing
|
||||
:kbd:`S` rotates a tile around the y-axis.
|
||||
|
||||
.. image:: img/gridmap_menu.png
|
||||
![](img/gridmap_menu.png)
|
||||
|
||||
Holding :kbd:`Shift` and dragging with the left mouse button will draw a selection
|
||||
box. You can duplicate or clear the selected area using the respective menu
|
||||
options.
|
||||
|
||||
.. image:: img/gridmap_select.png
|
||||
![](img/gridmap_select.png)
|
||||
|
||||
In the menu, you can also change the axis you're drawing on, as well as shift
|
||||
the drawing plane higher or lower on its axis.
|
||||
|
||||
.. image:: img/gridmap_shift_axis.png
|
||||
![](img/gridmap_shift_axis.png)
|
||||
|
||||
Using GridMap in code
|
||||
---------------------
|
||||
|
@ -34,7 +34,7 @@ In the tree case, this would be the tree itself.
|
||||
In our example, we would use a `Spatial` node as the root node of
|
||||
the scene. Your scene tree would look like this:
|
||||
|
||||
.. image:: img/multimesh_scene_tree.png
|
||||
![](img/multimesh_scene_tree.png)
|
||||
|
||||
.. note:: For simplicity's sake, this tutorial uses built-in primitives.
|
||||
|
||||
@ -43,9 +43,9 @@ toolbar, you should see an extra button called `MultiMesh` next to `View`.
|
||||
Click it and select *Populate surface* in the dropdown menu. A new window titled
|
||||
*Populate MultiMesh* will pop up.
|
||||
|
||||
.. image:: img/multimesh_toolbar.png
|
||||
![](img/multimesh_toolbar.png)
|
||||
|
||||
.. image:: img/multimesh_settings.png
|
||||
![](img/multimesh_settings.png)
|
||||
|
||||
MultiMesh settings
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
@ -101,6 +101,6 @@ result, you can delete the mesh instance used as the source mesh.
|
||||
|
||||
The end result should look like this:
|
||||
|
||||
.. image:: img/multimesh_result.png
|
||||
![](img/multimesh_result.png)
|
||||
|
||||
To change the result, repeat the previous steps with different parameters.
|
||||
|
@ -13,11 +13,11 @@ At first, this seems easy. For simple games, this way of thinking may even be en
|
||||
|
||||
Angles in three dimensions are most commonly referred to as "Euler Angles".
|
||||
|
||||
.. image:: img/transforms_euler.png
|
||||
![](img/transforms_euler.png)
|
||||
|
||||
Euler angles were introduced by mathematician Leonhard Euler in the early 1700s.
|
||||
|
||||
.. image:: img/transforms_euler_himself.png
|
||||
![](img/transforms_euler_himself.png)
|
||||
|
||||
This way of representing 3D rotations was groundbreaking at the time, but it has several shortcomings when used in game development (which is to be expected from a guy with a funny
|
||||
hat).
|
||||
@ -42,7 +42,7 @@ from 3 different angles, depending on *the order of the rotations*.
|
||||
|
||||
Following is a visualization of rotation axes (in X, Y, Z order) in a gimbal (from Wikipedia). As you can see, the orientation of each axis depends on the rotation of the previous one:
|
||||
|
||||
.. image:: img/transforms_gimbal.gif
|
||||
![](img/transforms_gimbal.gif)
|
||||
|
||||
You may be wondering how this affects you. Let's look at a practical example:
|
||||
|
||||
@ -50,11 +50,11 @@ Imagine you are working on a first-person controller (e.g. an FPS game). Moving
|
||||
|
||||
In this case to achieve the desired effect, rotation must be applied first in the *Y* axis ("up" in this case, since Godot uses a "Y-Up" orientation), followed by rotation in the *X* axis.
|
||||
|
||||
.. image:: img/transforms_rotate1.gif
|
||||
![](img/transforms_rotate1.gif)
|
||||
|
||||
If we were to apply rotation in the *X* axis first, and then in *Y*, the effect would be undesired:
|
||||
|
||||
.. image:: img/transforms_rotate2.gif
|
||||
![](img/transforms_rotate2.gif)
|
||||
|
||||
Depending on the type of game or effect desired, the order in which you want axis rotations to be applied may differ. Therefore, applying rotations in X, Y, and Z is not enough: you also need a *rotation order*.
|
||||
|
||||
@ -63,11 +63,11 @@ Interpolation
|
||||
|
||||
Another problem with using Euler angles is interpolation. Imagine you want to transition between two different camera or enemy positions (including rotations). One logical way to approach this is to interpolate the angles from one position to the next. One would expect it to look like this:
|
||||
|
||||
.. image:: img/transforms_interpolate1.gif
|
||||
![](img/transforms_interpolate1.gif)
|
||||
|
||||
But this does not always have the expected effect when using angles:
|
||||
|
||||
.. image:: img/transforms_interpolate2.gif
|
||||
![](img/transforms_interpolate2.gif)
|
||||
|
||||
The camera actually rotated the opposite direction!
|
||||
|
||||
@ -110,16 +110,16 @@ Following the OpenGL convention, `X` is the *Right* axis, `Y` is the *Up* axis a
|
||||
|
||||
Together with the *basis*, a transform also has an *origin*. This is a *Vector3* specifying how far away from the actual origin `(0, 0, 0)` this transform is. Combining the *basis* with the *origin*, a *transform* efficiently represents a unique translation, rotation, and scale in space.
|
||||
|
||||
.. image:: img/transforms_camera.png
|
||||
![](img/transforms_camera.png)
|
||||
|
||||
|
||||
One way to visualize a transform is to look at an object's 3D gizmo while in "local space" mode.
|
||||
|
||||
.. image:: img/transforms_local_space.png
|
||||
![](img/transforms_local_space.png)
|
||||
|
||||
The gizmo's arrows show the `X`, `Y`, and `Z` axes (in red, green, and blue respectively) of the basis, while the gizmo's center is at the object's origin.
|
||||
|
||||
.. image:: img/transforms_gizmo.png
|
||||
![](img/transforms_gizmo.png)
|
||||
|
||||
For more information on the mathematics of vectors and transforms, please read the `doc_vector_math` tutorials.
|
||||
|
||||
|
@ -36,16 +36,16 @@ Setup
|
||||
animating within Godot.
|
||||
|
||||
For this tutorial, we will be using a single image to construct our character.
|
||||
Download it from :download:`gBot_pieces.png <img/gBot_pieces.png>` or save the
|
||||
Download it from :download:`gBot_pieces.png) <img/gBot_pieces.png)>` or save the
|
||||
image below.
|
||||
|
||||
.. image:: img/gBot_pieces.png
|
||||
![](img/gBot_pieces.png)
|
||||
|
||||
It is also advised to download the final character image
|
||||
:download:`gBot_complete.png <img/gBot_complete.png>` to have a good reference
|
||||
:download:`gBot_complete.png) <img/gBot_complete.png)>` to have a good reference
|
||||
for putting the different pieces together.
|
||||
|
||||
.. image:: img/gBot_complete.png
|
||||
![](img/gBot_complete.png)
|
||||
|
||||
Creating the polygons
|
||||
---------------------
|
||||
@ -57,22 +57,22 @@ created as a root for the polygons.
|
||||
Begin with a `Polygon2D` node. There is no need to place it anywhere in the
|
||||
scene for now, so simply create it like this:
|
||||
|
||||
.. image:: img/skel2d1.png
|
||||
![](img/skel2d1.png)
|
||||
|
||||
Select it and assign the texture with the character pieces you have downloaded
|
||||
before:
|
||||
|
||||
.. image:: img/skel2d2.png
|
||||
![](img/skel2d2.png)
|
||||
|
||||
Drawing a polygon directly is not advised. Instead, open the "UV" dialog for the
|
||||
polygon:
|
||||
|
||||
.. image:: img/skel2d3.png
|
||||
![](img/skel2d3.png)
|
||||
|
||||
Head over to the *Points* mode, select the pencil and draw a polygon around the
|
||||
desired piece:
|
||||
|
||||
.. image:: img/skel2d4.png
|
||||
![](img/skel2d4.png)
|
||||
|
||||
Duplicate the polygon node and give it a proper name. Then, enter the "UV"
|
||||
dialog again and replace the old polygon with another one in the new desired
|
||||
@ -84,11 +84,11 @@ the previous polygon instead of drawing a new one.
|
||||
After moving the polygon, remember to update the UV by selecting Edit -> "Polygon
|
||||
-> UV" in the Polygon 2D UV Editor.
|
||||
|
||||
.. image:: img/skel2d5.png
|
||||
![](img/skel2d5.png)
|
||||
|
||||
Keep doing this until you mapped all pieces.
|
||||
|
||||
.. image:: img/skel2d6.png
|
||||
![](img/skel2d6.png)
|
||||
|
||||
You will notice that pieces for nodes appear in the same layout as they do in
|
||||
the original texture. This is because by default, when you draw a polygon, the
|
||||
@ -98,12 +98,12 @@ Rearrange the pieces and build the character. This should be pretty quick. There
|
||||
is no need to change pivots, so don't bother making sure rotation pivots for
|
||||
each piece are right; you can leave them be for now.
|
||||
|
||||
.. image:: img/skel2d7.png
|
||||
![](img/skel2d7.png)
|
||||
|
||||
Ah, the visual order of the pieces is not correct yet, as some are covering
|
||||
wrong pieces. Rearrange the order of the nodes to fix this:
|
||||
|
||||
.. image:: img/skel2d8.png
|
||||
![](img/skel2d8.png)
|
||||
|
||||
And there you go! It was definitely much easier than in the cutout tutorial.
|
||||
|
||||
@ -113,23 +113,23 @@ Creating the skeleton
|
||||
Create a `Skeleton2D` node as a child of the root node. This will be the base
|
||||
of our skeleton:
|
||||
|
||||
.. image:: img/skel2d9.png
|
||||
![](img/skel2d9.png)
|
||||
|
||||
Create a `Bone2D` node as a child of the skeleton. Put it on the hip (usually
|
||||
skeletons start here). The bone will be pointing to the right, but you can
|
||||
ignore this for now.
|
||||
|
||||
.. image:: img/skel2d10.png
|
||||
![](img/skel2d10.png)
|
||||
|
||||
Keep creating bones in hierarchy and naming them accordingly.
|
||||
|
||||
.. image:: img/skel2d11.png
|
||||
![](img/skel2d11.png)
|
||||
|
||||
At the end of this chain, there will be a *jaw* node. It is, again, very short
|
||||
and pointing to the right. This is normal for bones without children. The length
|
||||
of *tip* bones can be changed with a property in the inspector:
|
||||
|
||||
.. image:: img/skel2d12.png
|
||||
![](img/skel2d12.png)
|
||||
|
||||
In this case, we don't need to rotate the bone (coincidentally the jaw points
|
||||
right in the sprite), but in case you need to, feel free to do it. Again, this
|
||||
@ -138,14 +138,14 @@ length or a specific rotation.
|
||||
|
||||
Keep going and build the whole skeleton:
|
||||
|
||||
.. image:: img/skel2d13.png
|
||||
![](img/skel2d13.png)
|
||||
|
||||
You will notice that all bones raise an annoying warning about a missing rest
|
||||
pose. This means that it's time to set one. Go to the *skeleton* node and create
|
||||
a rest pose. This pose is the default one, you can come back to it anytime you
|
||||
want (which is very handy for animating):
|
||||
|
||||
.. image:: img/skel2d14.png
|
||||
![](img/skel2d14.png)
|
||||
|
||||
The warnings will go away. If you modify the skeleton (add/remove bones) you
|
||||
will need to set the rest pose again.
|
||||
@ -157,15 +157,15 @@ Select the previously created polygons and assign the skeleton node to their
|
||||
`Skeleton` property. This will ensure that they can eventually be deformed by
|
||||
it.
|
||||
|
||||
.. image:: img/skel2d15.png
|
||||
![](img/skel2d15.png)
|
||||
|
||||
Click the property highlighted above and select the skeleton node:
|
||||
|
||||
.. image:: img/skel2d16.png
|
||||
![](img/skel2d16.png)
|
||||
|
||||
Again, open the UV editor for the polygon and go to the *Bones* section.
|
||||
|
||||
.. image:: img/skel2d17.png
|
||||
![](img/skel2d17.png)
|
||||
|
||||
You will not be able to paint weights yet. For this you need to synchronize the
|
||||
list of bones from the skeleton with the polygon. This step is done only once
|
||||
@ -174,13 +174,13 @@ It ensures that your rigging information is kept in the polygon, even if a
|
||||
skeleton node is accidentally lost or the skeleton modified. Push the "Sync
|
||||
Bones to Polygon" button to sync the list.
|
||||
|
||||
.. image:: img/skel2d18.png
|
||||
![](img/skel2d18.png)
|
||||
|
||||
The list of bones will automatically appear. By default, your polygon has no
|
||||
weight assigned to any of them. Select the bones you want to assign weight to
|
||||
and paint them:
|
||||
|
||||
.. image:: img/skel2d19.png
|
||||
![](img/skel2d19.png)
|
||||
|
||||
Points in white have a full weight assigned, while points in black are not
|
||||
influenced by the bone. If the same point is painted white for multiple bones,
|
||||
@ -188,7 +188,7 @@ the influence will be distributed amongst them (so usually there is not that
|
||||
much need to use shades in-between unless you want to polish the bending
|
||||
effect).
|
||||
|
||||
.. image:: img/skel2d20.gif
|
||||
![](img/skel2d20.gif)
|
||||
|
||||
After painting the weights, animating the bones (NOT the polygons!) will have
|
||||
the desired effect of modifying and bending the polygons accordingly. As you
|
||||
@ -197,7 +197,7 @@ only need to animate bones in this approach, work becomes much easier!
|
||||
But it's not all roses. Trying to animate bones that bend the polygon will often
|
||||
yield unexpected results:
|
||||
|
||||
.. image:: img/skel2d21.gif
|
||||
![](img/skel2d21.gif)
|
||||
|
||||
This happens because Godot generates internal triangles that connect the points
|
||||
when drawing the polygon. They don't always bend the way you would expect. To
|
||||
@ -210,18 +210,18 @@ Internal vertices
|
||||
Open the UV menu for each bone again and go to the *Points* section. Add some
|
||||
internal vertices in the regions where you expect the geometry to bend:
|
||||
|
||||
.. image:: img/skel2d22.png
|
||||
![](img/skel2d22.png)
|
||||
|
||||
Now, go to the *Polygon* section and redraw your own polygons with more detail.
|
||||
Imagine that, as your polygons bend, you need to make sure they deform the least
|
||||
possible, so experiment a bit to find the right setup.
|
||||
|
||||
.. image:: img/skel2d23.png
|
||||
![](img/skel2d23.png)
|
||||
|
||||
Once you start drawing, the original polygon will disappear and you will be free
|
||||
to create your own:
|
||||
|
||||
.. image:: img/skel2d24.png
|
||||
![](img/skel2d24.png)
|
||||
|
||||
This amount of detail is usually fine, though you may want to have more
|
||||
fine-grained control over where triangles go. Experiment by yourself until you
|
||||
@ -232,4 +232,4 @@ painting! Go to the *Bones* section again to assign them to the right bones.
|
||||
|
||||
Once you are all set, you will get much better results:
|
||||
|
||||
.. image:: img/skel2d25.gif
|
||||
![](img/skel2d25.gif)
|
||||
|
@ -31,7 +31,7 @@ new scene which contains the imported one. Afterwards, point the `AnimationTree`
|
||||
|
||||
This is how it's done in the `Third Person Shooter demo <https://github.com/godotengine/tps-demo>`_, for reference:
|
||||
|
||||
.. image:: img/animtree1.png
|
||||
![](img/animtree1.png)
|
||||
|
||||
A new scene was created for the player with a `KinematicBody` as root. Inside this scene, the original `.dae` (Collada) file was instantiated
|
||||
and an `AnimationTree` node was created.
|
||||
@ -47,7 +47,7 @@ There are three main types of nodes that can be used in `AnimationTree`:
|
||||
|
||||
To set a root node in `AnimationTree`, a few types are available:
|
||||
|
||||
.. image:: img/animtree2.png
|
||||
![](img/animtree2.png)
|
||||
|
||||
* `AnimationNodeAnimation`: Selects an animation from the list and plays it. This is the simplest root node, and generally not used directly as root.
|
||||
* `AnimationNodeBlendTree`: Contains many *blend* type nodes, such as mix, blend2, blend3, one shot, etc. This is one of the most commonly used roots.
|
||||
@ -60,13 +60,13 @@ Blend tree
|
||||
|
||||
An `AnimationNodeBlendTree` can contain both root and regular nodes used for blending. Nodes are added to the graph from a menu:
|
||||
|
||||
.. image:: img/animtree3.png
|
||||
![](img/animtree3.png)
|
||||
|
||||
All blend trees contain an `Output` node by default, and something has to be connected to it in order for animations to play.
|
||||
|
||||
The easiest way to test this functionality is to connect an `Animation` node to it directly:
|
||||
|
||||
.. image:: img/animtree4.png
|
||||
![](img/animtree4.png)
|
||||
|
||||
This will simply play back the animation. Make sure that the `AnimationTree` is active for something to actually happen.
|
||||
|
||||
@ -77,21 +77,21 @@ Blend2 / Blend3
|
||||
|
||||
These nodes will blend between two or three inputs by a user-specified blend value:
|
||||
|
||||
.. image:: img/animtree5.gif
|
||||
![](img/animtree5.gif)
|
||||
|
||||
For more complex blending, it is advised to use blend spaces instead.
|
||||
|
||||
Blending can also use filters, i.e. you can control individually which tracks go through the blend function.
|
||||
This is very useful for layering animations on top of each other.
|
||||
|
||||
.. image:: img/animtree6.png
|
||||
![](img/animtree6.png)
|
||||
|
||||
OneShot
|
||||
^^^^^^^
|
||||
|
||||
This node will execute a sub-animation and return once it finishes. Blend times for fading in and out can be customized, as well as filters.
|
||||
|
||||
.. image:: img/animtree6b.gif
|
||||
![](img/animtree6b.gif)
|
||||
|
||||
Seek
|
||||
^^^^
|
||||
@ -130,23 +130,23 @@ BlendSpace2D
|
||||
`BlendSpace2D` is a node to do advanced blending in two dimensions. Points are added to a two-dimensional space and then a position
|
||||
can be controlled to determine blending:
|
||||
|
||||
.. image:: img/animtree7.gif
|
||||
![](img/animtree7.gif)
|
||||
|
||||
The ranges in X and Y can be controlled (and labeled for convenience). By default, points can be placed anywhere (just right-click on
|
||||
the coordinate system or use the *add point* button) and triangles will be generated automatically using Delaunay.
|
||||
|
||||
.. image:: img/animtree8.gif
|
||||
![](img/animtree8.gif)
|
||||
|
||||
It is also possible to draw the triangles manually by disabling the *auto triangle* option, though this is rarely necessary:
|
||||
|
||||
.. image:: img/animtree9.png
|
||||
![](img/animtree9.png)
|
||||
|
||||
Finally, it is possible to change the blend mode. By default, blending happens by interpolating points inside the closest triangle.
|
||||
When dealing with 2D animations (frame by frame), you may want to switch to *Discrete* mode.
|
||||
Alternatively, if you want to keep the current play position when switching between discrete animations, there is a *Carry* mode.
|
||||
This mode can be changed in the *Blend* menu:
|
||||
|
||||
.. image:: img/animtree10.png
|
||||
![](img/animtree10.png)
|
||||
|
||||
BlendSpace1D
|
||||
^^^^^^^^^^^^
|
||||
@ -159,11 +159,11 @@ StateMachine
|
||||
This node acts as a state machine with root nodes as states. Root nodes can be created and connected via lines. States are connected via *Transitions*,
|
||||
which are connections with special properties. Transitions are uni-directional, but two can be used to connect in both directions.
|
||||
|
||||
.. image:: img/animtree11.gif
|
||||
![](img/animtree11.gif)
|
||||
|
||||
There are many types of transition:
|
||||
|
||||
.. image:: img/animtree12.png
|
||||
![](img/animtree12.png)
|
||||
|
||||
* *Immediate*: Will switch to the next state immediately. The current state will end and blend into the beginning of the new one.
|
||||
* *Sync*: Will switch to the next state immediately, but will seek the new state to the playback position of the old state.
|
||||
@ -171,7 +171,7 @@ There are many types of transition:
|
||||
|
||||
Transitions also have a few properties. Click any transition and it will be displayed in the inspector dock:
|
||||
|
||||
.. image:: img/animtree13.png
|
||||
![](img/animtree13.png)
|
||||
|
||||
* *Switch Mode* is the transition type (see above), it can be modified after creation here.
|
||||
* *Auto Advance* will turn on the transition automatically when this state is reached. This works best with the *At End* switch mode.
|
||||
@ -191,7 +191,7 @@ This allows animating characters in a way where steps actually match the floor b
|
||||
When playing back the animation in Godot, it is possible to select this bone as the *root motion track*. Doing so will cancel the bone
|
||||
transformation visually (the animation will stay in place).
|
||||
|
||||
.. image:: img/animtree14.png
|
||||
![](img/animtree14.png)
|
||||
|
||||
Afterwards, the actual motion can be retrieved via the `AnimationTree` API as a transform:
|
||||
|
||||
@ -206,7 +206,7 @@ This can be fed to functions such as `KinematicBody.move_and_slide` to control t
|
||||
There is also a tool node, `RootMotionView`, that can be placed in a scene and will act as a custom floor for your
|
||||
character and animations (this node is disabled by default during the game).
|
||||
|
||||
.. image:: img/animtree15.gif
|
||||
![](img/animtree15.gif)
|
||||
|
||||
|
||||
Controlling from code
|
||||
@ -222,14 +222,14 @@ or reuse nodes with a complex layout (such as a state machine or blend space) in
|
||||
The actual animation data is contained in the `AnimationTree` node and is accessed via properties.
|
||||
Check the "Parameters" section of the `AnimationTree` node to see all the parameters that can be modified in real-time:
|
||||
|
||||
.. image:: img/animtree16.png
|
||||
![](img/animtree16.png)
|
||||
|
||||
This is handy because it makes it possible to animate them from an `AnimationPlayer`, or even the `AnimationTree` itself,
|
||||
allowing the realization of very complex animation logic.
|
||||
|
||||
To modify these values from code, the property path must be obtained. This is done easily by hovering the mouse over any of the parameters:
|
||||
|
||||
.. image:: img/animtree17.png
|
||||
![](img/animtree17.png)
|
||||
|
||||
Which allows setting them or reading them:
|
||||
|
||||
@ -270,4 +270,4 @@ gdscript GDScript
|
||||
|
||||
The state machine must be running before you can travel. Make sure to either call `start()` or choose a node to **Autoplay on Load**.
|
||||
|
||||
.. image:: img/animtree18.png
|
||||
![](img/animtree18.png)
|
||||
|
@ -57,7 +57,7 @@ For this tutorial, we will use as demo content the pieces of the
|
||||
`GBot <https://www.youtube.com/watch?v=S13FrWuBMx4&list=UUckpus81gNin1aV8WSffRKw>`__
|
||||
character, created by Andreas Esau.
|
||||
|
||||
.. image:: img/tuto_cutout_walk.gif
|
||||
![](img/tuto_cutout_walk.gif)
|
||||
|
||||
Get your assets: :download:`gbot_resources.zip <files/gbot_resources.zip>`.
|
||||
|
||||
@ -66,31 +66,31 @@ Setting up the rig
|
||||
|
||||
Create an empty Node2D as root of the scene, we will work under it:
|
||||
|
||||
.. image:: img/tuto_cutout1.png
|
||||
![](img/tuto_cutout1.png)
|
||||
|
||||
The first node of the model is the hip.
|
||||
Generally, both in 2D and 3D, the hip is the root of the skeleton. This
|
||||
makes it easier to animate:
|
||||
|
||||
.. image:: img/tuto_cutout2.png
|
||||
![](img/tuto_cutout2.png)
|
||||
|
||||
Next will be the torso. The torso needs to be a child of the hip, so
|
||||
create a child sprite and load the torso texture, later accommodate it properly:
|
||||
|
||||
.. image:: img/tuto_cutout3.png
|
||||
![](img/tuto_cutout3.png)
|
||||
|
||||
This looks good. Let's see if our hierarchy works as a skeleton by
|
||||
rotating the torso. We can do this be pressing :kbd:`E` to enter rotate mode,
|
||||
and dragging with the left mouse button. To exit rotate mode hit :kbd:`ESC`.
|
||||
|
||||
.. image:: img/tutovec_torso1.gif
|
||||
![](img/tutovec_torso1.gif)
|
||||
|
||||
The rotation pivot is wrong and needs to be adjusted.
|
||||
|
||||
This small cross in the middle of the `Sprite` is
|
||||
the rotation pivot:
|
||||
|
||||
.. image:: img/tuto_cutout4.png
|
||||
![](img/tuto_cutout4.png)
|
||||
|
||||
Adjusting the pivot
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
@ -98,25 +98,25 @@ Adjusting the pivot
|
||||
The pivot can be adjusted by changing the *offset* property in the
|
||||
Sprite:
|
||||
|
||||
.. image:: img/tuto_cutout5.png
|
||||
![](img/tuto_cutout5.png)
|
||||
|
||||
The pivot can also be adjusted *visually*. While hovering over the
|
||||
desired pivot point, press :kbd:`V` to move the pivot there for the
|
||||
selected Sprite. There is also a tool in the tool bar that has a
|
||||
similar function.
|
||||
|
||||
.. image:: img/tutovec_torso2.gif
|
||||
![](img/tutovec_torso2.gif)
|
||||
|
||||
Continue adding body pieces, starting with the
|
||||
right arm. Make sure to put each sprite in its correct place in the hierarchy,
|
||||
so its rotations and translations are relative to its parent:
|
||||
|
||||
.. image:: img/tuto_cutout6.png
|
||||
![](img/tuto_cutout6.png)
|
||||
|
||||
With the left arm there's a problem. In 2D, child nodes appear in front of
|
||||
their parents:
|
||||
|
||||
.. image:: img/tuto_cutout7.png
|
||||
![](img/tuto_cutout7.png)
|
||||
|
||||
We want the left arm to appear *behind*
|
||||
the hip and the torso. We could move the left arm nodes behind the hip (above
|
||||
@ -142,12 +142,12 @@ Create another RemoteTransform2D node inside the first and call it `remote_hand_
|
||||
Use the `Remote Path` property of the two new nodes to target the `arm_l` and
|
||||
`hand_l` sprites respectively:
|
||||
|
||||
.. image:: img/tuto_cutout9.png
|
||||
![](img/tuto_cutout9.png)
|
||||
|
||||
Moving the `RemoteTransform2D` nodes now moves the sprites. So we can create
|
||||
animations by adjusting the `RemoteTransform2D` transforms:
|
||||
|
||||
.. image:: img/tutovec_torso4.gif
|
||||
![](img/tutovec_torso4.gif)
|
||||
|
||||
Completing the skeleton
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -155,7 +155,7 @@ Completing the skeleton
|
||||
Complete the skeleton by following the same steps for the rest of the
|
||||
parts. The resulting scene should look similar to this:
|
||||
|
||||
.. image:: img/tuto_cutout10.png
|
||||
![](img/tuto_cutout10.png)
|
||||
|
||||
The resulting rig will be easy to animate. By selecting the nodes and
|
||||
rotating them you can animate forward kinematics (FK) efficiently.
|
||||
@ -178,15 +178,15 @@ nodes are called skeletons.
|
||||
As an example, let's turn the right arm into a skeleton. To create
|
||||
a skeleton, a chain of nodes must be selected from top to bottom:
|
||||
|
||||
.. image:: img/tuto_cutout11.png
|
||||
![](img/tuto_cutout11.png)
|
||||
|
||||
Then, click on the Skeleton menu and select `Make Bones`.
|
||||
|
||||
.. image:: img/tuto_cutout12.png
|
||||
![](img/tuto_cutout12.png)
|
||||
|
||||
This will add bones covering the arm, but the result may be surprising.
|
||||
|
||||
.. image:: img/tuto_cutout13.png
|
||||
![](img/tuto_cutout13.png)
|
||||
|
||||
Why does the hand lack a bone? In Godot, a bone connects a
|
||||
node with its parent. And there's currently no child of the hand node.
|
||||
@ -197,12 +197,12 @@ but `Position2D` is preferred because it's
|
||||
visible in the editor. The endpoint node will ensure that the last bone
|
||||
has orientation.
|
||||
|
||||
.. image:: img/tuto_cutout14.png
|
||||
![](img/tuto_cutout14.png)
|
||||
|
||||
Now select the whole chain, from the endpoint to the arm and create
|
||||
bones:
|
||||
|
||||
.. image:: img/tuto_cutout15.png
|
||||
![](img/tuto_cutout15.png)
|
||||
|
||||
The result resembles a skeleton a lot more, and now the arm and forearm
|
||||
can be selected and animated.
|
||||
@ -216,11 +216,11 @@ Godot has connected the hip node to the scene root with a bone, and we don't
|
||||
want that. To fix this, select the root and hip node, open the Skeleton menu,
|
||||
click `clear bones`.
|
||||
|
||||
.. image:: img/tuto_cutout15_2.png
|
||||
![](img/tuto_cutout15_2.png)
|
||||
|
||||
Your final skeleton should look something like this:
|
||||
|
||||
.. image:: img/tuto_cutout16.png
|
||||
![](img/tuto_cutout16.png)
|
||||
|
||||
You might have noticed a second set of endpoints in the hands. This will make
|
||||
sense soon.
|
||||
@ -244,21 +244,21 @@ To create an IK chain, select a chain of bones from endpoint to
|
||||
the base for the chain. For example, to create an IK chain for the right
|
||||
leg, select the following:
|
||||
|
||||
.. image:: img/tuto_cutout17.png
|
||||
![](img/tuto_cutout17.png)
|
||||
|
||||
Then enable this chain for IK. Go to Edit > Make IK Chain.
|
||||
|
||||
.. image:: img/tuto_cutout18.png
|
||||
![](img/tuto_cutout18.png)
|
||||
|
||||
As a result, the base of the chain will turn *Yellow*.
|
||||
|
||||
.. image:: img/tuto_cutout19.png
|
||||
![](img/tuto_cutout19.png)
|
||||
|
||||
Once the IK chain is set-up grab any child or grand-child of the base of the
|
||||
chain (e.g. a foot) and move it. You'll see the rest of the chain adjust as you
|
||||
adjust its position.
|
||||
|
||||
.. image:: img/tutovec_torso5.gif
|
||||
![](img/tutovec_torso5.gif)
|
||||
|
||||
Animation tips
|
||||
~~~~~~~~~~~~~~
|
||||
@ -273,7 +273,7 @@ Setting keyframes and excluding properties
|
||||
Special contextual elements appear in the top toolbar when the animation editor
|
||||
window is open:
|
||||
|
||||
.. image:: img/tuto_cutout20.png
|
||||
![](img/tuto_cutout20.png)
|
||||
|
||||
The key button inserts location, rotation, and scale keyframes for the
|
||||
selected objects or bones at the current playhead position.
|
||||
@ -310,7 +310,7 @@ toolbar.
|
||||
their current arrangement. This pose can now be recalled when necessary in
|
||||
your game by playing the "rest" animation you've created.
|
||||
|
||||
.. image:: img/tuto_cutout21.png
|
||||
![](img/tuto_cutout21.png)
|
||||
|
||||
Modifying rotation only
|
||||
~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -322,7 +322,7 @@ Location and scale are rarely used.
|
||||
So when inserting keys, you might find it convenient to have only the "rot"
|
||||
toggle active most of the time:
|
||||
|
||||
.. image:: img/tuto_cutout22.png
|
||||
![](img/tuto_cutout22.png)
|
||||
|
||||
This will avoid the creation of unwanted animation tracks for position
|
||||
and scale.
|
||||
@ -348,7 +348,7 @@ Node2D-inheriting nodes. When planning your rig, think about the movements it
|
||||
will need to perform and give some thought to how you'll use "Behind Parent"
|
||||
and/or RemoteTransform2D nodes. They provide overlapping functionality.
|
||||
|
||||
.. image:: img/tuto_cutout23.png
|
||||
![](img/tuto_cutout23.png)
|
||||
|
||||
Setting easing curves for multiple keys
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
@ -360,7 +360,7 @@ To apply the same easing curve to multiple keyframes at once:
|
||||
will open the transition editor.
|
||||
3. In the transition editor, click on the desired curve to apply it.
|
||||
|
||||
.. image:: img/tuto_cutout24.png
|
||||
![](img/tuto_cutout24.png)
|
||||
|
||||
2D Skeletal deform
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
@ -28,7 +28,7 @@ The AnimationPlayer node type is the data container for your animations.
|
||||
One AnimationPlayer node can hold multiple animations, that can
|
||||
automatically transition to one another.
|
||||
|
||||
.. figure:: img/animation_create_animationplayer.png
|
||||
.. figure:: img/animation_create_animationplayer.png)
|
||||
:alt: The AnimationPlayer node
|
||||
|
||||
The AnimationPlayer node
|
||||
@ -36,14 +36,14 @@ automatically transition to one another.
|
||||
After creating one click on the AnimationPlayer node in the Node tab to
|
||||
open the Animation Panel at the bottom of the viewport.
|
||||
|
||||
.. figure:: img/animation_animation_panel.png
|
||||
.. figure:: img/animation_animation_panel.png)
|
||||
:alt: The animation panel position
|
||||
|
||||
The animation panel position
|
||||
|
||||
It consists of four parts:
|
||||
|
||||
.. figure:: img/animation_animation_panel_overview.png
|
||||
.. figure:: img/animation_animation_panel_overview.png)
|
||||
:alt: The animation panel
|
||||
|
||||
The animation panel
|
||||
@ -62,7 +62,7 @@ A keyframe defines the value of a property at a certain point in time.
|
||||
Diamond shapes represent keyframes in the timeline. A line between two
|
||||
keyframes indicates that the value hasn't changed.
|
||||
|
||||
.. figure:: img/animation_keyframes.png
|
||||
.. figure:: img/animation_keyframes.png)
|
||||
:alt: Keyframes in Godot
|
||||
|
||||
Keyframes in Godot
|
||||
@ -70,7 +70,7 @@ keyframes indicates that the value hasn't changed.
|
||||
The engine interpolates values between keyframes, resulting in a gradual
|
||||
change in values over time.
|
||||
|
||||
.. figure:: img/animation_illustration.png
|
||||
.. figure:: img/animation_illustration.png)
|
||||
:alt: Two keyframes are all it takes to obtain a smooth motion
|
||||
|
||||
Two keyframes are all it takes to obtain a smooth motion
|
||||
@ -78,7 +78,7 @@ change in values over time.
|
||||
The timeline lets you insert keyframes and change their timing. It also
|
||||
defines how long the animation is.
|
||||
|
||||
.. figure:: img/animation_timeline.png
|
||||
.. figure:: img/animation_timeline.png)
|
||||
:alt: The timeline in the animation panel
|
||||
|
||||
The timeline in the animation panel
|
||||
@ -87,7 +87,7 @@ Each line of the Animation Panel is an animation track. Normal and
|
||||
Transform tracks reference node properties. Their name or id is a path
|
||||
to the node and the affected property.
|
||||
|
||||
.. figure:: img/animation_normal_track.png
|
||||
.. figure:: img/animation_normal_track.png)
|
||||
:alt: Example of Normal animation tracks
|
||||
|
||||
Example of Normal animation tracks
|
||||
@ -108,7 +108,7 @@ Scene setup
|
||||
For this tutorial, we'll create a Sprite node with an AnimationPlayer as
|
||||
its child. We will animate the sprite to move between two points on the screen.
|
||||
|
||||
.. figure:: img/animation_animation_player_tree.png
|
||||
.. figure:: img/animation_animation_player_tree.png)
|
||||
:alt: Our scene setup
|
||||
|
||||
Our scene setup
|
||||
@ -132,7 +132,7 @@ animation editor. From the list select "New" (|Add
|
||||
Animation|) to add a new animation. And Enter a name for the animation in the
|
||||
dialog box.
|
||||
|
||||
.. figure:: img/animation_create_new_animation.png
|
||||
.. figure:: img/animation_create_new_animation.png)
|
||||
:alt: Add a new animation
|
||||
|
||||
Add a new animation
|
||||
@ -143,7 +143,7 @@ Adding a track
|
||||
To add a new track for our sprite, select it and take a look in the
|
||||
toolbar:
|
||||
|
||||
.. figure:: img/animation_convenience_buttons.png
|
||||
.. figure:: img/animation_convenience_buttons.png)
|
||||
:alt: Convenience buttons
|
||||
|
||||
Convenience buttons
|
||||
@ -160,7 +160,7 @@ property, Godot asks whether it should set it up for us. Click **Create**.
|
||||
This creates a new track and our first keyframe at the beginning of
|
||||
the timeline:
|
||||
|
||||
.. figure:: img/animation_track.png
|
||||
.. figure:: img/animation_track.png)
|
||||
:alt: The sprite track
|
||||
|
||||
The sprite track
|
||||
@ -175,7 +175,7 @@ Let's say, we want it to take 2 seconds to go to the other point. By
|
||||
default the animation is set to last only 1 second, so change this in
|
||||
the timeline controls in animation panel's lower panel to 2.
|
||||
|
||||
.. figure:: img/animation_set_length.png
|
||||
.. figure:: img/animation_set_length.png)
|
||||
:alt: Animation length
|
||||
|
||||
Animation length
|
||||
@ -193,7 +193,7 @@ Click on the "Play from beginning" (|Play from beginning|) button.
|
||||
|
||||
Yay! Our animation runs:
|
||||
|
||||
.. figure:: img/animation_simple.gif
|
||||
.. figure:: img/animation_simple.gif)
|
||||
:alt: The animation
|
||||
|
||||
The animation
|
||||
@ -206,7 +206,7 @@ Godot always calculates the frames between two keyframes. In a loop, the
|
||||
first keyframe is also the last keyframe, if no keyframe is specified at
|
||||
the end.
|
||||
|
||||
.. figure:: img/animation_loop.png
|
||||
.. figure:: img/animation_loop.png)
|
||||
:alt: Animation loop
|
||||
|
||||
Animation loop
|
||||
@ -221,7 +221,7 @@ Track settings
|
||||
Each track has a settings panel at the end, where you can set the update
|
||||
mode, the track interpolation, and the loop mode.
|
||||
|
||||
.. figure:: img/animation_track_settings.png
|
||||
.. figure:: img/animation_track_settings.png)
|
||||
:alt: Track settings
|
||||
|
||||
Track settings
|
||||
@ -241,7 +241,7 @@ values. This can be:
|
||||
could use the Capture mode to move a node that's located anywhere
|
||||
to a specific location.
|
||||
|
||||
.. figure:: img/animation_track_rate.png
|
||||
.. figure:: img/animation_track_rate.png)
|
||||
:alt: Track mode
|
||||
|
||||
Track mode
|
||||
@ -258,7 +258,7 @@ the keyframes. These interpolation modes are supported:
|
||||
- Cubic: Set the value based on a cubic function calculation between
|
||||
the two keyframes
|
||||
|
||||
.. figure:: img/animation_track_interpolation.png
|
||||
.. figure:: img/animation_track_interpolation.png)
|
||||
:alt: Track interpolation
|
||||
|
||||
Track interpolation
|
||||
@ -271,7 +271,7 @@ of a robotic movement.
|
||||
Godot supports two loop modes, which affect the animation if it's set to
|
||||
loop:
|
||||
|
||||
.. figure:: img/animation_track_loop_modes.png
|
||||
.. figure:: img/animation_track_loop_modes.png)
|
||||
:alt: Loop modes
|
||||
|
||||
Loop modes
|
||||
@ -294,7 +294,7 @@ a small keyframe button for all the sprite's properties. Click on
|
||||
this button and Godot automatically adds a track and keyframe to the
|
||||
current animation.
|
||||
|
||||
.. figure:: img/animation_properties_keyframe.png
|
||||
.. figure:: img/animation_properties_keyframe.png)
|
||||
:alt: Keyframes for other properties
|
||||
|
||||
Keyframes for other properties
|
||||
@ -306,7 +306,7 @@ For advanced use and to edit keyframes in detail, You can click on them
|
||||
to bring up the keyframe editor in the inspector. You can use this to
|
||||
directly edit its values.
|
||||
|
||||
.. figure:: img/animation_keyframe_editor_key.png
|
||||
.. figure:: img/animation_keyframe_editor_key.png)
|
||||
:alt: Keyframe editor editing a key
|
||||
|
||||
Keyframe editor editing a key
|
||||
@ -348,7 +348,7 @@ controls.
|
||||
|
||||
Select "Add Call Method Track" from the list of possible track types.
|
||||
|
||||
.. figure:: img/animation_add_call_method_track.png
|
||||
.. figure:: img/animation_add_call_method_track.png)
|
||||
:alt: Add Call Method Track
|
||||
|
||||
Add Call Method Track
|
||||
@ -356,7 +356,7 @@ Select "Add Call Method Track" from the list of possible track types.
|
||||
Select the `AudioStreamPlayer` node in the selection
|
||||
window. Godot adds the track with the reference to the node.
|
||||
|
||||
.. figure:: img/animation_select_audiostreamplayer.png
|
||||
.. figure:: img/animation_select_audiostreamplayer.png)
|
||||
:alt: Select AudioStreamPlayer
|
||||
|
||||
Select AudioStreamPlayer
|
||||
@ -366,7 +366,7 @@ click the "Insert Key" option. This will bring up a list of methods
|
||||
that can be called for the AudioStreamPlayer node. Select the first
|
||||
one.
|
||||
|
||||
.. image:: img/animation_method_options.png
|
||||
![](img/animation_method_options.png)
|
||||
|
||||
When Godot reaches the keyframe, Godot calls the
|
||||
`AudioStreamPlayer` node's "play" function and the stream
|
||||
@ -375,11 +375,11 @@ plays.
|
||||
You can change its position by dragging it on the timeline, you can also
|
||||
click on the keyframe and use the keyframe settings in the inspector.
|
||||
|
||||
.. image:: img/animation_call_method_keyframe.png
|
||||
![](img/animation_call_method_keyframe.png)
|
||||
|
||||
.. |Play from beginning| image:: img/animation_play_from_beginning.png
|
||||
.. |Add Animation| image:: img/animation_add.png
|
||||
.. |Add track| image:: img/animation_add_track.png
|
||||
.. |Play from beginning| image:: img/animation_play_from_beginning.png)
|
||||
.. |Add Animation| image:: img/animation_add.png)
|
||||
.. |Add track| image:: img/animation_add_track.png)
|
||||
|
||||
Using RESET tracks
|
||||
------------------
|
||||
|
@ -67,7 +67,7 @@ AspectRatioContainer node to match your video's aspect ratio. You can use math
|
||||
formulas in the inspector to help yourself. Remember to make one of the operands
|
||||
a float. Otherwise, the division's result will always be an integer.
|
||||
|
||||
.. figure:: img/playing_videos_aspect_ratio_container.png
|
||||
.. figure:: img/playing_videos_aspect_ratio_container.png)
|
||||
:figclass: figure-w480
|
||||
:align: center
|
||||
:alt: AspectRatioContainer's Ratio property being modified in the editor inspector
|
||||
|
@ -22,13 +22,13 @@ New created action is always an active action bound to object. There are
|
||||
several ways to place an active action into NLA track,
|
||||
one is of course doing it in `NLA Editor`
|
||||
|
||||
.. image:: img/nla_editor.jpg
|
||||
.. image:: img/nla_pushdown.jpg
|
||||
![](img/nla_editor.jpg
|
||||
![](img/nla_pushdown.jpg
|
||||
|
||||
Or it can be done stashing the action in `Dope Sheet`
|
||||
|
||||
.. image:: img/dope_sheet.jpg
|
||||
.. image:: img/stash_action.jpg
|
||||
![](img/dope_sheet.jpg
|
||||
![](img/stash_action.jpg
|
||||
|
||||
**2. Check mute status of NLA tracks**
|
||||
|
||||
@ -36,18 +36,18 @@ An NLA track can be `mute` or `unmute`, the exporter will export all
|
||||
the `mute` NLA track as a separate action, while blends all the `unmute`
|
||||
NLA tracks into every action (including the action action) being exported.
|
||||
|
||||
.. image:: img/nla_strip.jpg
|
||||
![](img/nla_strip.jpg
|
||||
|
||||
**3. Export the scene**
|
||||
|
||||
Make sure the `Export Stashed Actions` option has been turned on.
|
||||
|
||||
.. image:: img/stash_action_option.jpg
|
||||
![](img/stash_action_option.jpg
|
||||
|
||||
Then all the stashed actions, as well as the active action, are exported
|
||||
to an AnimationPlayer.
|
||||
|
||||
.. image:: img/in_godot.jpg
|
||||
![](img/in_godot.jpg
|
||||
|
||||
|
||||
Constraints
|
||||
|
@ -30,7 +30,7 @@ Sometimes you don't want some objects exported (e.g. high-res models used for
|
||||
baking). An object will not be exported if it is not rendered in the scene.
|
||||
This can be set in the outliner:
|
||||
|
||||
.. image:: img/hide.jpg
|
||||
![](img/hide.jpg
|
||||
|
||||
Objects hidden in the viewport will be exported, but will be hidden in the
|
||||
Godot scene.
|
||||
|
@ -11,7 +11,7 @@ Lights
|
||||
Sun, point and spot lamps are all exported from Blender along with many of their
|
||||
properties:
|
||||
|
||||
.. image:: img/light_properties.jpg
|
||||
![](img/light_properties.jpg
|
||||
|
||||
There are some things to note:
|
||||
|
||||
|
@ -20,7 +20,7 @@ exporter will fall back to exporting the material from Blender.
|
||||
Where the exporter searches for the `.tres` file is determined by the "Material
|
||||
Search Paths" option:
|
||||
|
||||
.. image:: img/material_search.jpg
|
||||
![](img/material_search.jpg
|
||||
|
||||
This can take the value of:
|
||||
- Project Directory - Attempts to find the `project.Godot` and recursively
|
||||
@ -62,8 +62,8 @@ The default configuration of material exporting would keep all the materials int
|
||||
the `escn` file. There is an option which could enable generating external `.material`
|
||||
file when the `escn` file opens in Godot.
|
||||
|
||||
.. image:: img/external_mat_option.jpg
|
||||
![](img/external_mat_option.jpg
|
||||
|
||||
`.material` file can be assigned to any material slot to be a external resource.
|
||||
|
||||
.. image:: img/gd_dot_material.jpg
|
||||
![](img/gd_dot_material.jpg
|
||||
|
@ -4,7 +4,7 @@ Physics properties
|
||||
Exporting physics properties is done by enabling "Rigid Body" in Blender's
|
||||
physics tab:
|
||||
|
||||
.. image:: img/enable_physics.png
|
||||
![](img/enable_physics.png)
|
||||
|
||||
.. important::
|
||||
By default, a single Blender object with rigid body enabled will export as
|
||||
@ -17,7 +17,7 @@ Blender only has the concept of "Active" and "Passive" rigid bodies. These
|
||||
turn into Static and RigidBody nodes. To create a kinematic body, enable the
|
||||
"animated" checkbox on an "Active" body:
|
||||
|
||||
.. image:: img/body_type.jpg
|
||||
![](img/body_type.jpg
|
||||
|
||||
Collision shapes
|
||||
----------------
|
||||
@ -27,7 +27,7 @@ of the collision shapes are also not present. However, almost all of the
|
||||
options in Blender's rigid body collision and rigid body dynamics interfaces
|
||||
are supported:
|
||||
|
||||
.. image:: img/collision_shapes.jpg
|
||||
![](img/collision_shapes.jpg
|
||||
|
||||
There are the following caveats:
|
||||
- Not all of the collision shapes are supported. Only `Mesh`, `Convex
|
||||
@ -51,7 +51,7 @@ graphical meshes, but by default, the exporter will export a mesh along with the
|
||||
collision shape. To only export the collision shape, set the object's maximum
|
||||
draw type to Wire:
|
||||
|
||||
.. image:: img/col_only.png
|
||||
![](img/col_only.png)
|
||||
|
||||
This will also influence how the object is shown in Blender's viewport.
|
||||
Most of the time, you want your collision geometry to be shown see-through when
|
||||
|
@ -1,7 +1,7 @@
|
||||
Skeleton
|
||||
========
|
||||
|
||||
.. image:: img/armature.jpg
|
||||
![](img/armature.jpg
|
||||
|
||||
Rest Bone
|
||||
---------
|
||||
|
@ -18,7 +18,7 @@ program such as Blender, and then bring it back into Godot.
|
||||
|
||||
To export a scene in the editor go to **Project > Tools > Export GLTF...**
|
||||
|
||||
.. image:: img/gltf_godot_export.png
|
||||
![](img/gltf_godot_export.png)
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
@ -33,7 +33,7 @@ To change the import parameters of an asset in Godot (again, keep in mind
|
||||
import parameters are only present in non-native Godot resource types)
|
||||
select the relevant resource in the filesystem dock:
|
||||
|
||||
.. image:: img/asset_workflow1.png
|
||||
![](img/asset_workflow1.png)
|
||||
|
||||
Then, after adjusting the parameters, press "Reimport". These parameters
|
||||
will only be used for this asset and on future reimports.
|
||||
@ -51,7 +51,7 @@ those specific parameters changed. To do this, select every asset you want
|
||||
to reimport in the file system. In the import tab there will now be a
|
||||
checkbox to the left of every import parameter.
|
||||
|
||||
.. image:: img/reimport_multiple.png
|
||||
![](img/reimport_multiple.png)
|
||||
|
||||
Select the checkbox of the parameters you want to change on your imported
|
||||
assets, then change the parameters normally. Finally, click the reimport
|
||||
@ -71,11 +71,11 @@ Files generated
|
||||
Importing will add an extra `<asset>.import` file, containing the import
|
||||
configuration. Make sure to commit these to your version control system!
|
||||
|
||||
.. image:: img/asset_workflow4.png
|
||||
![](img/asset_workflow4.png)
|
||||
|
||||
Additionally, extra assets will be preset in the hidden `res://.import` folder:
|
||||
|
||||
.. image:: img/asset_workflow5.png
|
||||
![](img/asset_workflow5.png)
|
||||
|
||||
If any of the files present in this folder is erased (or the whole folder), the
|
||||
asset or assets will be reimported automatically. As such, committing this folder
|
||||
@ -90,7 +90,7 @@ Some source assets can be imported as different types of resources.
|
||||
For this, select the relevant type of resource desired and
|
||||
press "Reimport":
|
||||
|
||||
.. image:: img/asset_workflow2.png
|
||||
![](img/asset_workflow2.png)
|
||||
|
||||
|
||||
Changing default import parameters
|
||||
@ -101,7 +101,7 @@ Changing the defaults per project can be achieved by using the
|
||||
"Preset.." Menu. Besides some resource types offering presets,
|
||||
the default setting can be saved and cleared too:
|
||||
|
||||
.. image:: img/asset_workflow3.png
|
||||
![](img/asset_workflow3.png)
|
||||
|
||||
Simplicity is key!
|
||||
------------------
|
||||
|
@ -54,7 +54,7 @@ This saves SFX artists the need to add reverb to the sound effects,
|
||||
reducing their size greatly and ensuring correct trimming. Say no to SFX
|
||||
with baked reverb!
|
||||
|
||||
.. image:: img/reverb.png
|
||||
![](img/reverb.png)
|
||||
|
||||
As you can see above, sound effects become huge with reverb added.
|
||||
|
||||
|
@ -19,7 +19,7 @@ Godot can import the following image formats:
|
||||
- Supports HDR (highly recommended for panorama skies).
|
||||
- JPEG (`.jpg`, `.jpeg`)
|
||||
- Doesn't support transparency per the format's limitations.
|
||||
- PNG (`.png`)
|
||||
- PNG (`.png)`)
|
||||
- Precision is limited to 8 bits per channel upon importing (no HDR images).
|
||||
- Truevision Targa (`.tga`)
|
||||
- SVG (`.svg`, `.svgz`)
|
||||
@ -45,7 +45,7 @@ efficient.
|
||||
|
||||
Import options are vast:
|
||||
|
||||
.. image:: img/image_import1.png
|
||||
![](img/image_import1.png)
|
||||
|
||||
Detect 3D
|
||||
~~~~~~~~~
|
||||
@ -96,11 +96,11 @@ advantages and disadvantages (|good| = best, |bad| = worst):
|
||||
| Load Time | |regular| Normal | |bad| Slow | |bad| Slow | |good| Fast |
|
||||
+----------------+------------------------+-------------------------------+-------------------------+------------------------------------------------------+
|
||||
|
||||
.. |bad| image:: img/bad.png
|
||||
.. |bad| image:: img/bad.png)
|
||||
|
||||
.. |good| image:: img/good.png
|
||||
.. |good| image:: img/good.png)
|
||||
|
||||
.. |regular| image:: img/regular.png
|
||||
.. |regular| image:: img/regular.png)
|
||||
|
||||
HDR Mode
|
||||
~~~~~~~~
|
||||
@ -193,7 +193,7 @@ Fix Alpha Border
|
||||
This puts pixels of the same surrounding color in transition from transparency to non transparency. It helps mitigate the outline effect when exporting images
|
||||
from Photoshop and the like.
|
||||
|
||||
.. image:: img/fixedborder.png
|
||||
![](img/fixedborder.png)
|
||||
|
||||
It's a good idea to leave it on by default, unless specific values are needed.
|
||||
|
||||
|
@ -133,7 +133,7 @@ import a scene with:
|
||||
* External scenes: Save each of the root nodes of the imported scenes as a separate scene.
|
||||
* Single scene: A single scene file with everything built in.
|
||||
|
||||
.. image:: img/scene_import1.png
|
||||
![](img/scene_import1.png)
|
||||
|
||||
As different developers have different needs, this import process is highly customizable.
|
||||
|
||||
@ -142,7 +142,7 @@ Import options
|
||||
|
||||
The importer has several options, which will be discussed below:
|
||||
|
||||
.. image:: img/scene_import2.png
|
||||
![](img/scene_import2.png)
|
||||
|
||||
Nodes
|
||||
~~~~~
|
||||
@ -303,7 +303,7 @@ Godot provides many options regarding how animation data is dealt with. Some exp
|
||||
3DS Max or Maya, need many animations put into the same timeline or, at worst, put
|
||||
each animation in a separate file.
|
||||
|
||||
.. image:: img/scene_import3.png
|
||||
![](img/scene_import3.png)
|
||||
|
||||
Import of animations is enabled by default.
|
||||
|
||||
@ -399,7 +399,7 @@ if the source asset changes (source `.dae`, `.gltf`, `.obj` file re-exported fro
|
||||
It is possible, however, to make local modifications by using *Scene Inheritance*. Try to open the imported scene and the
|
||||
following dialog will appear:
|
||||
|
||||
.. image:: img/scene_import4.png
|
||||
![](img/scene_import4.png)
|
||||
|
||||
In inherited scenes, the only limitations for modifications are:
|
||||
|
||||
@ -466,7 +466,7 @@ On import, it will create a `staticbody` with
|
||||
a collision node as a child. The collision node will have one of a number of predefined shapes,
|
||||
depending on Blender's empty draw type:
|
||||
|
||||
.. image:: img/3dimp_BlenderEmptyDrawTypes.png
|
||||
![](img/3dimp_BlenderEmptyDrawTypes.png)
|
||||
|
||||
- Single arrow will create a `rayshape`.
|
||||
- Cube will create a `boxshape`.
|
||||
|
@ -117,6 +117,6 @@ Select the `.csv` file and access the **Import** dock to define import
|
||||
options. You can toggle the compression of the imported translations, and
|
||||
select the delimiter to use when parsing the CSV file.
|
||||
|
||||
.. image:: img/import_csv.png
|
||||
![](img/import_csv.png)
|
||||
|
||||
Be sure to click **Reimport** after any change to these options.
|
||||
|
@ -49,7 +49,7 @@ Audio buses
|
||||
|
||||
Audio buses can be found in the bottom panel of the Godot editor:
|
||||
|
||||
.. image:: img/audio_buses1.png
|
||||
![](img/audio_buses1.png)
|
||||
|
||||
An *audio bus* (also called an *audio channel*) can be considered a place that
|
||||
audio is channeled through on the way to playback through a device's speakers.
|
||||
@ -65,7 +65,7 @@ the left. The destination bus can be specified for each of the non-master audio
|
||||
buses. Routing always passes audio from buses on the right to buses further
|
||||
to the left. This avoids infinite routing loops.
|
||||
|
||||
.. image:: img/audio_buses2.png
|
||||
![](img/audio_buses2.png)
|
||||
|
||||
In the above image, the output of *Bus 2* has been routed to the *Master* bus.
|
||||
|
||||
@ -75,7 +75,7 @@ Playback of audio through a bus
|
||||
To test passing audio to a bus, create an AudioStreamPlayer node, load an
|
||||
AudioStream and select a target bus for playback:
|
||||
|
||||
.. image:: img/audio_buses3.png
|
||||
![](img/audio_buses3.png)
|
||||
|
||||
Finally, toggle the **Playing** property to **On** and sound will flow.
|
||||
|
||||
@ -89,7 +89,7 @@ Adding effects
|
||||
Audio buses can contain all sorts of effects. These effects modify the sound in
|
||||
one way or another and are applied in order.
|
||||
|
||||
.. image:: img/audio_buses4.png
|
||||
![](img/audio_buses4.png)
|
||||
|
||||
Try them all out to get a sense of how they alter sound. Here follows a short
|
||||
description of the available effects:
|
||||
@ -281,7 +281,7 @@ There is no need to disable buses manually when not in use. Godot detects
|
||||
that the bus has been silent for a few seconds and disables it (including
|
||||
all effects).
|
||||
|
||||
.. figure:: img/audio_buses5.png
|
||||
.. figure:: img/audio_buses5.png)
|
||||
|
||||
Disabled buses have a blue VU meter instead of a red-green one.
|
||||
|
||||
|
@ -26,7 +26,7 @@ played back often.
|
||||
AudioStreamPlayer
|
||||
-----------------
|
||||
|
||||
.. image:: img/audio_stream_player.png
|
||||
![](img/audio_stream_player.png)
|
||||
|
||||
This is the standard, non-positional stream player. It can play to any bus.
|
||||
In 5.1 sound setups, it can send audio to stereo mix or front speakers.
|
||||
@ -34,7 +34,7 @@ In 5.1 sound setups, it can send audio to stereo mix or front speakers.
|
||||
AudioStreamPlayer2D
|
||||
-------------------
|
||||
|
||||
.. image:: img/audio_stream_2d.png
|
||||
![](img/audio_stream_2d.png)
|
||||
|
||||
This is a variant of AudioStreamPlayer, but emits sound in a 2D positional
|
||||
environment. When close to the left of the screen, the panning will go left.
|
||||
@ -47,12 +47,12 @@ When close to the right side, it will go right.
|
||||
different reverb or sound qualities to handle action happening in a
|
||||
particular parts of your game world.
|
||||
|
||||
.. image:: img/audio_stream_2d_area.png
|
||||
![](img/audio_stream_2d_area.png)
|
||||
|
||||
AudioStreamPlayer3D
|
||||
-------------------
|
||||
|
||||
.. image:: img/audio_stream_3d.png
|
||||
![](img/audio_stream_3d.png)
|
||||
|
||||
This is a variant of AudioStreamPlayer, but emits sound in a 3D positional
|
||||
environment. Depending on the location of the player relative to the screen,
|
||||
@ -60,7 +60,7 @@ it can position sound in stereo, 5.1 or 7.1 depending on the chosen audio setup.
|
||||
|
||||
Similar to AudioStreamPlayer2D, an Area can divert the sound to an audio bus.
|
||||
|
||||
.. image:: img/audio_stream_3d_area.png
|
||||
![](img/audio_stream_3d_area.png)
|
||||
|
||||
Unlike for 2D, the 3D version of AudioStreamPlayer has a few more advanced options:
|
||||
|
||||
@ -74,13 +74,13 @@ and wet audio to separate buses. This is useful when you have several reverb
|
||||
configurations for different types of rooms. This is done by enabling this type
|
||||
of reverb in the **Reverb Bus** section of the Area's properties:
|
||||
|
||||
.. image:: img/audio_stream_reverb_bus.png
|
||||
![](img/audio_stream_reverb_bus.png)
|
||||
|
||||
At the same time, a special bus layout is created where each area receives the
|
||||
reverb info from each area. A Reverb effect needs to be created and configured
|
||||
in each reverb bus to complete the setup for the desired effect:
|
||||
|
||||
.. image:: img/audio_stream_reverb_bus2.png
|
||||
![](img/audio_stream_reverb_bus2.png)
|
||||
|
||||
The Area's **Reverb Bus** section also has a parameter named **Uniformity**.
|
||||
Some types of rooms bounce sounds more than others (like a warehouse), so
|
||||
@ -96,7 +96,7 @@ perceived as an increase or decrease in the pitch of the emitted sound.
|
||||
Godot can track velocity changes in the AudioStreamPlayer3D and Camera nodes.
|
||||
Both nodes have this property, which must be enabled manually:
|
||||
|
||||
.. image:: img/audio_stream_doppler.png
|
||||
![](img/audio_stream_doppler.png)
|
||||
|
||||
Enable it by setting it depending on how objects will be moved:
|
||||
use **Idle** for objects moved using `_process`, or **Physics**
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user