浏览代码

Removing trailing whitespace

With `sed -i $(rg -l '[[:blank:]]*$' -g'!classes') -e 's/[[:blank:]]*$//g'`
Rémi Verschelde 6 年之前
父节点
当前提交
4ef06a4135
共有 69 个文件被更改,包括 739 次插入740 次删除
  1. 2 2
      README.md
  2. 1 1
      _templates/layout.html
  3. 2 3
      community/contributing/docs_writing_guidelines.rst
  4. 3 3
      community/contributing/updating_the_class_reference.rst
  5. 1 1
      content/3d/making_trees.rst
  6. 1 1
      development/compiling/compiling_for_ios.rst
  7. 1 1
      development/compiling/compiling_for_x11.rst
  8. 1 1
      development/compiling/packaging_godot.rst
  9. 1 1
      development/cpp/core_types.rst
  10. 45 45
      development/file_formats/tscn.rst
  11. 1 1
      getting_started/editor/external_editor.rst
  12. 1 1
      getting_started/scripting/c_sharp/c_sharp_features.rst
  13. 3 3
      getting_started/scripting/gdscript/gdscript_advanced.rst
  14. 2 2
      getting_started/scripting/gdscript/gdscript_format_string.rst
  15. 1 1
      getting_started/scripting/visual_script/getting_started.rst
  16. 2 2
      getting_started/scripting/visual_script/index.rst
  17. 21 21
      getting_started/scripting/visual_script/nodes_purposes.rst
  18. 1 1
      getting_started/step_by_step/intro_to_the_editor_interface.rst
  19. 9 9
      getting_started/step_by_step/scripting.rst
  20. 2 2
      getting_started/workflow/assets/escn_exporter/animation.rst
  21. 1 1
      getting_started/workflow/assets/escn_exporter/index.rst
  22. 1 1
      getting_started/workflow/assets/escn_exporter/mesh.rst
  23. 2 2
      getting_started/workflow/assets/escn_exporter/skeleton.rst
  24. 3 3
      getting_started/workflow/assets/importing_audio_samples.rst
  25. 3 3
      getting_started/workflow/assets/importing_images.rst
  26. 8 8
      getting_started/workflow/assets/importing_scenes.rst
  27. 19 19
      getting_started/workflow/export/exporting_for_ios.rst
  28. 1 1
      getting_started/workflow/export/exporting_for_uwp.rst
  29. 1 1
      getting_started/workflow/export/index.rst
  30. 72 72
      tutorials/2d/2d_lights_and_shadows.rst
  31. 10 10
      tutorials/2d/2d_movement.rst
  32. 87 87
      tutorials/3d/fps_tutorial/part_five.rst
  33. 51 51
      tutorials/3d/fps_tutorial/part_four.rst
  34. 34 34
      tutorials/3d/fps_tutorial/part_one.rst
  35. 58 58
      tutorials/3d/fps_tutorial/part_six.rst
  36. 56 56
      tutorials/3d/fps_tutorial/part_three.rst
  37. 1 1
      tutorials/3d/fps_tutorial/part_two.rst
  38. 1 1
      tutorials/3d/introduction_to_3d.rst
  39. 3 3
      tutorials/3d/using_gridmaps.rst
  40. 3 3
      tutorials/3d/using_transforms.rst
  41. 32 32
      tutorials/3d/vertex_displacement_with_shaders.rst
  42. 7 7
      tutorials/animation/cutout_animation.rst
  43. 14 14
      tutorials/assetlib/uploading_to_assetlib.rst
  44. 4 4
      tutorials/assetlib/using_assetlib.rst
  45. 1 1
      tutorials/audio/index.rst
  46. 2 2
      tutorials/debug/overview_of_debugging_tools.rst
  47. 3 3
      tutorials/gui/custom_gui_controls.rst
  48. 1 1
      tutorials/gui/gui_skinning.rst
  49. 3 3
      tutorials/inputs/custom_mouse_cursor.rst
  50. 4 4
      tutorials/inputs/inputevent.rst
  51. 1 1
      tutorials/io/background_loading.rst
  52. 2 2
      tutorials/io/encrypting_save_games.rst
  53. 2 2
      tutorials/math/matrices_and_transforms.rst
  54. 6 6
      tutorials/math/vector_math.rst
  55. 5 5
      tutorials/math/vectors_advanced.rst
  56. 2 2
      tutorials/misc/running_code_in_the_editor.rst
  57. 9 9
      tutorials/networking/high_level_multiplayer.rst
  58. 12 12
      tutorials/physics/kinematic_character_2d.rst
  59. 7 7
      tutorials/physics/physics_introduction.rst
  60. 6 6
      tutorials/platform/android_in_app_purchases.rst
  61. 1 1
      tutorials/plugins/editor/import_plugins.rst
  62. 1 1
      tutorials/plugins/gdnative/files/cpp_example/SConstruct
  63. 2 2
      tutorials/plugins/gdnative/gdnative-cpp-example.rst
  64. 37 37
      tutorials/shading/migrating_to_godot_shader_language.rst
  65. 1 1
      tutorials/shading/shader_materials.rst
  66. 3 3
      tutorials/viewports/multiple_resolutions.rst
  67. 35 35
      tutorials/viewports/using_viewport_as_texture.rst
  68. 19 19
      tutorials/viewports/viewports.rst
  69. 1 1
      tutorials/vr/vr_primer.rst

+ 2 - 2
README.md

@@ -61,12 +61,12 @@ or:
 make SPHINXBUILD=~/.local/bin/sphinx-build html
 make SPHINXBUILD=~/.local/bin/sphinx-build html
 ```
 ```
 
 
-The compilation might take some time as the `classes/` folder contains many files to parse.  
+The compilation might take some time as the `classes/` folder contains many files to parse.
 You can then test the changes live by opening `_build/html/index.html` in your favorite browser.
 You can then test the changes live by opening `_build/html/index.html` in your favorite browser.
 
 
 ### Building with Sphinx on Windows
 ### Building with Sphinx on Windows
 
 
-On Windows, you need to: 
+On Windows, you need to:
 * Download the Python installer [here](https://www.python.org/downloads/).
 * Download the Python installer [here](https://www.python.org/downloads/).
 * Install Python. Don't forget to check the "Add Python to PATH" box.
 * Install Python. Don't forget to check the "Add Python to PATH" box.
 * Use the above `pip` commands.
 * Use the above `pip` commands.

+ 1 - 1
_templates/layout.html

@@ -9,6 +9,6 @@
     <link rel="alternate" hreflang="pt-br" href="http://docs.godotengine.org/pt-br/" />
     <link rel="alternate" hreflang="pt-br" href="http://docs.godotengine.org/pt-br/" />
     <link rel="alternate" hreflang="uk" href="http://docs.godotengine.org/uk/" />
     <link rel="alternate" hreflang="uk" href="http://docs.godotengine.org/uk/" />
     <link rel="alternate" hreflang="zh-cn" href="http://docs.godotengine.org/zh-cn/" />
     <link rel="alternate" hreflang="zh-cn" href="http://docs.godotengine.org/zh-cn/" />
-    <link rel="alternate" hreflang="x-default" href="http://docs.godotengine.org/" />    
+    <link rel="alternate" hreflang="x-default" href="http://docs.godotengine.org/" />
     {{ super() }}
     {{ super() }}
 {% endblock %}
 {% endblock %}

+ 2 - 3
community/contributing/docs_writing_guidelines.rst

@@ -56,7 +56,6 @@ Active:
 ::
 ::
 
 
     The dog bit the man.
     The dog bit the man.
-    
 
 
 **Don't** use the passive voice:
 **Don't** use the passive voice:
 
 
@@ -400,10 +399,10 @@ and set the anisotropic filter quality to 16x in Project Settings
 
 
 Screenshot size should not exceed 1920x1080.
 Screenshot size should not exceed 1920x1080.
 
 
-When you need to highlight an area of the editor to show something, like a 
+When you need to highlight an area of the editor to show something, like a
 button or option, use a 2 pixel thick outline without a bevel.
 button or option, use a 2 pixel thick outline without a bevel.
 
 
 Before you add or replace any images in the documentation, they should be run through
 Before you add or replace any images in the documentation, they should be run through
 a png compressor to save size. The built in lossless compressor in programs like Krita
 a png compressor to save size. The built in lossless compressor in programs like Krita
 or Photoshop should be done. However you should also use a lossy one, such as `pngquant <https://pngquant.org/>`_
 or Photoshop should be done. However you should also use a lossy one, such as `pngquant <https://pngquant.org/>`_
-where almost no image quality is lost during compression.
+where almost no image quality is lost during compression.

+ 3 - 3
community/contributing/updating_the_class_reference.rst

@@ -3,7 +3,7 @@
 Contribute to the Class Reference
 Contribute to the Class Reference
 =================================
 =================================
 
 
-Godot ships with many nodes and singletons to help you develop your games in GDscript. Each is a class, documented in the :ref:`class reference <toc-class-ref>`. This reference is essential for anyone learning the engine: it is available both online and in the engine. 
+Godot ships with many nodes and singletons to help you develop your games in GDscript. Each is a class, documented in the :ref:`class reference <toc-class-ref>`. This reference is essential for anyone learning the engine: it is available both online and in the engine.
 
 
 But it's incomplete. Some methods, variables and signals lack descriptions. Others changed with recent releases and need updates. The developers can't write the entire reference on their own. Godot needs you, and all of us, to contribute.
 But it's incomplete. Some methods, variables and signals lack descriptions. Others changed with recent releases and need updates. The developers can't write the entire reference on their own. Godot needs you, and all of us, to contribute.
 
 
@@ -20,7 +20,7 @@ The class reference lies in the following XML files, in Godot's GitHub repositor
 
 
 There are 5 steps to update the class reference (full guide below):
 There are 5 steps to update the class reference (full guide below):
 
 
-1. Fork `Godot's repository <https://github.com/godotengine/godot>`_ 
+1. Fork `Godot's repository <https://github.com/godotengine/godot>`_
 2. Clone your fork on your computer
 2. Clone your fork on your computer
 3. Edit the class file in ``doc/classes/`` to write documentation
 3. Edit the class file in ``doc/classes/`` to write documentation
 4. Commit your changes and push them to your fork
 4. Commit your changes and push them to your fork
@@ -174,7 +174,7 @@ Our job is to add the missing text between these marks:
 -  <member></member>
 -  <member></member>
 -  <signal></signal>
 -  <signal></signal>
 
 
-Write in a clear and simple language. Always follow the :ref:`writing guidelines <doc_docs_writing_guidelines>` to keep your descriptions short and easy to read. **Do not leave empty lines** in the descriptions: each line in the XML file will result in a new paragraph. 
+Write in a clear and simple language. Always follow the :ref:`writing guidelines <doc_docs_writing_guidelines>` to keep your descriptions short and easy to read. **Do not leave empty lines** in the descriptions: each line in the XML file will result in a new paragraph.
 
 
 Here's how a class looks like in XML:
 Here's how a class looks like in XML:
 
 

+ 1 - 1
content/3d/making_trees.rst

@@ -12,7 +12,7 @@ The aim is to not focus on the modelling techniques (there are plenty of tutoria
 Start with a tree
 Start with a tree
 -----------------
 -----------------
 
 
-I took this tree from SketchFab: 
+I took this tree from SketchFab:
 
 
 .. image:: img/tree_base.png
 .. image:: img/tree_base.png
 
 

+ 1 - 1
development/compiling/compiling_for_ios.rst

@@ -40,7 +40,7 @@ for a Simulator executable.
 
 
 Additionally since some time Apple requires 64 bit version of application binary when you are uploading to iStore.
 Additionally since some time Apple requires 64 bit version of application binary when you are uploading to iStore.
 The best way to provide these is to create a bundle in which there are both 32bit and 64 binaries, so every device will be able to run the game.
 The best way to provide these is to create a bundle in which there are both 32bit and 64 binaries, so every device will be able to run the game.
-It can be done in three steps, first compile 32 bit version, then compile 64 bit version and then use ``lipo`` to bundle them into one fat binary, all those steps can be performed with following commands: 
+It can be done in three steps, first compile 32 bit version, then compile 64 bit version and then use ``lipo`` to bundle them into one fat binary, all those steps can be performed with following commands:
 
 
 ::
 ::
 
 

+ 1 - 1
development/compiling/compiling_for_x11.rst

@@ -62,7 +62,7 @@ Distro-specific oneliners
 +---------------+------------------------------------------------------------------------------------------------------------+
 +---------------+------------------------------------------------------------------------------------------------------------+
 | **OpenBSD**   | ::                                                                                                         |
 | **OpenBSD**   | ::                                                                                                         |
 |               |                                                                                                            |
 |               |                                                                                                            |
-|               |     pkg_add python scons png llvm yasm                                                                     | 
+|               |     pkg_add python scons png llvm yasm                                                                     |
 +---------------+------------------------------------------------------------------------------------------------------------+
 +---------------+------------------------------------------------------------------------------------------------------------+
 | **openSUSE**  | ::                                                                                                         |
 | **openSUSE**  | ::                                                                                                         |
 |               |                                                                                                            |
 |               |                                                                                                            |

+ 1 - 1
development/compiling/packaging_godot.rst

@@ -46,7 +46,7 @@ The contents of the ``._sc_`` file (when not empty) are read with the ConfigFile
 format as ``project.godot``, etc). So far it can contain a list of pre-loaded project in this
 format as ``project.godot``, etc). So far it can contain a list of pre-loaded project in this
 format:
 format:
 
 
-:: 
+::
 
 
   [init_projects]
   [init_projects]
   list=["demos/2d/platformer", "demos/2d/isometric"]
   list=["demos/2d/platformer", "demos/2d/isometric"]

+ 1 - 1
development/cpp/core_types.rst

@@ -104,7 +104,7 @@ memnew/memdelete also use a little C++ magic and notify Objects right
 after they are created, and right before they are deleted.
 after they are created, and right before they are deleted.
 
 
 For dynamic memory, the PoolVector<> template is provided. PoolVector is a
 For dynamic memory, the PoolVector<> template is provided. PoolVector is a
-standard vector class, and is very similar to vector in the C++ standard library. 
+standard vector class, and is very similar to vector in the C++ standard library.
 To create a PoolVector buffer, use this:
 To create a PoolVector buffer, use this:
 
 
 .. code:: cpp
 .. code:: cpp

+ 45 - 45
development/file_formats/tscn.rst

@@ -1,13 +1,13 @@
 TSCN file format
 TSCN file format
 ================
 ================
 
 
-A :code:`.tscn` File format is the "Text SCeNe" file format and represents 
-a single scene-tree inside Godot. TSCN files have the advantage of being 
-nearly human-readable and easy for version control systems to manage. During 
-import the TSCN files are compiled into binary :code:`.scn` files stored 
+A :code:`.tscn` File format is the "Text SCeNe" file format and represents
+a single scene-tree inside Godot. TSCN files have the advantage of being
+nearly human-readable and easy for version control systems to manage. During
+import the TSCN files are compiled into binary :code:`.scn` files stored
 inside the .import folder. This reduces the data size and speed up loading.
 inside the .import folder. This reduces the data size and speed up loading.
 
 
-The :code:`.escn` file format is identical to the TSCN file format, but is used to 
+The :code:`.escn` file format is identical to the TSCN file format, but is used to
 indicate to Godot that the file has been exported from another program and
 indicate to Godot that the file has been exported from another program and
 should not be edited by the user from within Godot.
 should not be edited by the user from within Godot.
 
 
@@ -21,17 +21,17 @@ File structure
 There are five main sections inside the TSCN File:
 There are five main sections inside the TSCN File:
 
 
 0. File Descriptor
 0. File Descriptor
-1. External resources 
+1. External resources
 2. Internal resources
 2. Internal resources
 3. Nodes
 3. Nodes
 4. Connections
 4. Connections
 
 
-The file descriptor looks like :code:`[gd_scene load_steps=1 format=2]` And 
-should be the first entry in the file. The load_steps parameter should (in 
-theory) be the number of resources within the file, though in practice its 
+The file descriptor looks like :code:`[gd_scene load_steps=1 format=2]` And
+should be the first entry in the file. The load_steps parameter should (in
+theory) be the number of resources within the file, though in practice its
 value seems not to matter.
 value seems not to matter.
 
 
-These sections should appear in order, but it can be hard to distinguish 
+These sections should appear in order, but it can be hard to distinguish
 them. The only difference between them is the first element in the heading
 them. The only difference between them is the first element in the heading
 for all of the items in the section.
 for all of the items in the section.
 For example, the heading of all external resources should start with
 For example, the heading of all external resources should start with
@@ -48,9 +48,9 @@ Where resource_type is one of:
 - sub_resource
 - sub_resource
 - node
 - node
 - connection
 - connection
- 
-Underneath every heading comes zero or more :code:`key = value` pairs. The 
-values can be complex datatypes such as arrays, transformations, colors, and 
+
+Underneath every heading comes zero or more :code:`key = value` pairs. The
+values can be complex datatypes such as arrays, transformations, colors, and
 so on. For example, a spatial node looks like:
 so on. For example, a spatial node looks like:
 
 
 ::
 ::
@@ -73,11 +73,11 @@ Other valid keywords include:
  - index (if two nodes have the same name)
  - index (if two nodes have the same name)
  - groups
  - groups
 
 
-The first node in the file should not have the :code:`parent=Path/To/Node` 
-entry in it's heading, and it is the scene root. All scene files should have 
-exactly one scene root. It it does not, Godot will fail to import the file. 
-The parent path of other nodes should be absolute, but without the scene 
-root's name. If it is a direct child of the scene root, it should be 
+The first node in the file should not have the :code:`parent=Path/To/Node`
+entry in it's heading, and it is the scene root. All scene files should have
+exactly one scene root. It it does not, Godot will fail to import the file.
+The parent path of other nodes should be absolute, but without the scene
+root's name. If it is a direct child of the scene root, it should be
 :code:`"."`. Here is an example scene tree (but without any node content).
 :code:`"."`. Here is an example scene tree (but without any node content).
 
 
 ::
 ::
@@ -86,9 +86,9 @@ root's name. If it is a direct child of the scene root, it should be
     [node name="Arm" parent="." type="Spatial"]     ; Parented to the scene root
     [node name="Arm" parent="." type="Spatial"]     ; Parented to the scene root
     [node name="Hand" parent="Arm" type="Spatial"]
     [node name="Hand" parent="Arm" type="Spatial"]
     [node name="Finger" parent="Arm/Hand" type="Spatial"]
     [node name="Finger" parent="Arm/Hand" type="Spatial"]
-    
-Similar to the internal resource, the document for each node is currently 
-incomplete. Fortunately it is easy to find out because you can simply 
+
+Similar to the internal resource, the document for each node is currently
+incomplete. Fortunately it is easy to find out because you can simply
 save a file with that node in it. Some example nodes are:
 save a file with that node in it. Some example nodes are:
 
 
 ::
 ::
@@ -154,7 +154,7 @@ Skeleton
 
 
 Skeleton node inherits Spatial node, besides that it may have a list
 Skeleton node inherits Spatial node, besides that it may have a list
 of bones described in key, value pair in the format :code:`bones/Id/Attribute=Value`,
 of bones described in key, value pair in the format :code:`bones/Id/Attribute=Value`,
-attributes of bone consists of 
+attributes of bone consists of
 
 
 - name
 - name
 - parent
 - parent
@@ -172,7 +172,7 @@ attributes of bone consists of
 
 
 4) :code:`pose` is the pose matrix use :code:`rest` as basis
 4) :code:`pose` is the pose matrix use :code:`rest` as basis
 
 
-5) :code:`bound_children` is a list of NodePath() points to 
+5) :code:`bound_children` is a list of NodePath() points to
    BoneAttachments belong to this bone
    BoneAttachments belong to this bone
 
 
 An example of a skeleton node with two bones:
 An example of a skeleton node with two bones:
@@ -199,7 +199,7 @@ BoneAttachment
 
 
 BoneAttachment node is an intermediate node to describe some node being parented
 BoneAttachment node is an intermediate node to describe some node being parented
 to a single bone in Skeleton node. The BoneAttachment has a :code:`bone_name=NameOfBone`,
 to a single bone in Skeleton node. The BoneAttachment has a :code:`bone_name=NameOfBone`,
-and the corresponding bone being the parent has the BoneAttachment node 
+and the corresponding bone being the parent has the BoneAttachment node
 in its :code:`bound_children` list.
 in its :code:`bound_children` list.
 
 
 An example of one MeshInstance parented to a bone in Skeleton:
 An example of one MeshInstance parented to a bone in Skeleton:
@@ -253,13 +253,13 @@ node will have an accompanying ArrayMesh resource. The ArrayMesh resource
 may be either internal or external to the TSCN file.
 may be either internal or external to the TSCN file.
 
 
 References to the resources are handled by id numbers in the resources heading.
 References to the resources are handled by id numbers in the resources heading.
-External resources and internal resource are referred to with 
-:code:`ExtResource(id)` and :code:`SubResource(id)`. Because there have 
+External resources and internal resource are referred to with
+:code:`ExtResource(id)` and :code:`SubResource(id)`. Because there have
 different methods to refer to internal and external resource, you can have
 different methods to refer to internal and external resource, you can have
 the same ID for both an internal and external resource.
 the same ID for both an internal and external resource.
 
 
 For example, to refer to the resource
 For example, to refer to the resource
-:code:`[ext_resource id=3 type="PackedScene" path=....]` you would use 
+:code:`[ext_resource id=3 type="PackedScene" path=....]` you would use
 :code:`ExtResource(3)`
 :code:`ExtResource(3)`
 
 
 External resources
 External resources
@@ -272,10 +272,10 @@ itself. An external resource consists of:
  - A type
  - A type
  - An ID
  - An ID
 
 
-Godot always generates absolute paths relative to the resource directory and 
-thus prefixed with :code:`res://`, but paths relative to the TSCN file's 
-location are also valid. 
- 
+Godot always generates absolute paths relative to the resource directory and
+thus prefixed with :code:`res://`, but paths relative to the TSCN file's
+location are also valid.
+
 Some example external resources are:
 Some example external resources are:
 
 
 ::
 ::
@@ -286,10 +286,10 @@ Some example external resources are:
 Internal resources
 Internal resources
 ~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~
 
 
-A TSCN file can contain meshes, materials and other data, and these are 
+A TSCN file can contain meshes, materials and other data, and these are
 contained in the internal resources section of the file. The heading
 contained in the internal resources section of the file. The heading
 for an internal resource looks similar to those of external resources, but
 for an internal resource looks similar to those of external resources, but
-does not have a path. Internal resources also have :code:`key=value` pairs 
+does not have a path. Internal resources also have :code:`key=value` pairs
 under each heading. For example, a capsule collision shape looks like:
 under each heading. For example, a capsule collision shape looks like:
 
 
 ::
 ::
@@ -298,10 +298,10 @@ under each heading. For example, a capsule collision shape looks like:
 
 
     radius = 0.5
     radius = 0.5
     height = 3.0
     height = 3.0
-    
-Some internal resource contain links to other internal resources (such as a 
-mesh having a material). In this case, the referring resource must appear 
-before the reference to it. Thus, in the internal resources section of the 
+
+Some internal resource contain links to other internal resources (such as a
+mesh having a material). In this case, the referring resource must appear
+before the reference to it. Thus, in the internal resources section of the
 file, order does matter.
 file, order does matter.
 
 
 Unfortunately, documentation on the formats for these subresources is not
 Unfortunately, documentation on the formats for these subresources is not
@@ -322,7 +322,7 @@ TSCN support two format of surface,
 - arrays
 - arrays
 - morph_arrays
 - morph_arrays
 
 
-    i) :code:`primitive` is an enumerate variable, :code:`primitive=4` which is 
+    i) :code:`primitive` is an enumerate variable, :code:`primitive=4` which is
        PRIMITIVE_TRIANGLES is frequently used.
        PRIMITIVE_TRIANGLES is frequently used.
 
 
     ii) :code:`arrays` as the name suggests is an array of array, it contains:
     ii) :code:`arrays` as the name suggests is an array of array, it contains:
@@ -336,7 +336,7 @@ TSCN support two format of surface,
         7) Bone weight array
         7) Bone weight array
         8) Vertex index array
         8) Vertex index array
 
 
-    iii) :code:`morph_arrays` is an array of morph, each morph is exactly an 
+    iii) :code:`morph_arrays` is an array of morph, each morph is exactly an
          :code:`arrays` without vertex index array.
          :code:`arrays` without vertex index array.
 
 
 An example of ArrayMesh:
 An example of ArrayMesh:
@@ -384,15 +384,15 @@ it includes:
 - imported
 - imported
 - enabled
 - enabled
 
 
-1) The :code:`type` must be put as the first attribute of each track. 
+1) The :code:`type` must be put as the first attribute of each track.
    The value of :code:`type` can be:
    The value of :code:`type` can be:
 
 
     - 'transform'
     - 'transform'
     - 'value'
     - 'value'
     - 'method'
     - 'method'
 
 
-2) The :code:`path` has the format :code:`NodePath(Path/To/Node:Attribute)`. 
-   It is the path from animation root node (property of AnimationPlayer) to the 
+2) The :code:`path` has the format :code:`NodePath(Path/To/Node:Attribute)`.
+   It is the path from animation root node (property of AnimationPlayer) to the
    animated node or attribute.
    animated node or attribute.
 
 
 3) The :code:`interp` is the method to interpolate frames from the keyframes.
 3) The :code:`interp` is the method to interpolate frames from the keyframes.
@@ -402,12 +402,12 @@ it includes:
     - 1 (linear)
     - 1 (linear)
     - 2 (cubic)
     - 2 (cubic)
 
 
-4) The :code:`keys` is the keyframes, it appears as a PoolRealArray() 
+4) The :code:`keys` is the keyframes, it appears as a PoolRealArray()
    but have different structure for track with different type
    but have different structure for track with different type
 
 
-    - A transform track use every 12 real number in the :code:`keys` to describte a keyframe. 
+    - A transform track use every 12 real number in the :code:`keys` to describte a keyframe.
       The first number is the timestamp, the second number is the transition (default 1.0
       The first number is the timestamp, the second number is the transition (default 1.0
-      in transform track), followed by a three number translation vector, followed by 
+      in transform track), followed by a three number translation vector, followed by
       four number rotation quaternion (x,y,z,w) and finally a three number scale vector.
       four number rotation quaternion (x,y,z,w) and finally a three number scale vector.
 
 
 ::
 ::

+ 1 - 1
getting_started/editor/external_editor.rst

@@ -5,7 +5,7 @@ Using an external text editor
 
 
 While Godot has an inbuilt text editor, some developers have a tendency to
 While Godot has an inbuilt text editor, some developers have a tendency to
 want to use a text editor they are familiar with. Godot provides this
 want to use a text editor they are familiar with. Godot provides this
-option via the options under 
+option via the options under
 ``Editor -> Editor Settings -> Text Editor -> External``
 ``Editor -> Editor Settings -> Text Editor -> External``
 
 
 .. image:: img/editor_settings.png
 .. image:: img/editor_settings.png

+ 1 - 1
getting_started/scripting/c_sharp/c_sharp_features.rst

@@ -140,7 +140,7 @@ It is possible to bind values when establishing a connection by passing an objec
     {
     {
         var plusButton = (Button)GetNode("PlusButton");
         var plusButton = (Button)GetNode("PlusButton");
         var minusButton = (Button)GetNode("MinusButton");
         var minusButton = (Button)GetNode("MinusButton");
-        
+
         plusButton.Connect("pressed", this, "ModifyValue", new object[] { 1 });
         plusButton.Connect("pressed", this, "ModifyValue", new object[] { 1 });
         minusButton.Connect("pressed", this, "ModifyValue", new object[] { -1 });
         minusButton.Connect("pressed", this, "ModifyValue", new object[] { -1 });
     }
     }

+ 3 - 3
getting_started/scripting/gdscript/gdscript_advanced.rst

@@ -10,7 +10,7 @@ This tutorial aims to be a quick reference for how to use GDScript more
 efficiently. It focuses on common cases specific to the language, but
 efficiently. It focuses on common cases specific to the language, but
 also covers a lot of information on dynamically typed languages.
 also covers a lot of information on dynamically typed languages.
 
 
-It's meant to be especially useful for programmers with little or no previous 
+It's meant to be especially useful for programmers with little or no previous
 experience with dynamically typed languages.
 experience with dynamically typed languages.
 
 
 Dynamic nature
 Dynamic nature
@@ -147,7 +147,7 @@ too. Some Examples:
 
 
         SomeClass instance = new SomeClass(); // Created as reference
         SomeClass instance = new SomeClass(); // Created as reference
         use_class(instance); // Passed as reference
         use_class(instance); // Passed as reference
-        // Garbage collector will get rid of it when not in 
+        // Garbage collector will get rid of it when not in
         // use and freeze your game randomly for a second
         // use and freeze your game randomly for a second
     }
     }
 
 
@@ -280,7 +280,7 @@ easily with dictionaries. Here's a simple battleship game example:
         if pos in board: # Something at that pos
         if pos in board: # Something at that pos
             if board[pos] == SHIP: # There was a ship! hit it
             if board[pos] == SHIP: # There was a ship! hit it
                 board[pos] = SHIP_HIT
                 board[pos] = SHIP_HIT
-            else: 
+            else:
                 print("Already hit here!") # Hey dude you already hit here
                 print("Already hit here!") # Hey dude you already hit here
         else: # Nothing, mark as water
         else: # Nothing, mark as water
             board[pos] = WATER_HIT
             board[pos] = WATER_HIT

+ 2 - 2
getting_started/scripting/gdscript/gdscript_format_string.rst

@@ -25,7 +25,7 @@ Examine this concrete GDScript example:
 
 
     # Define a format string with placeholder '%s'
     # Define a format string with placeholder '%s'
     var format_string = "We're waiting for %s."
     var format_string = "We're waiting for %s."
-    
+
     # Using the '%' operator, the placeholder is replaced with the desired value
     # Using the '%' operator, the placeholder is replaced with the desired value
     var actual_string = format_string % "Godot"
     var actual_string = format_string % "Godot"
 
 
@@ -78,7 +78,7 @@ format specifier with ``*``, see `dynamic padding`_):
 
 
     var format_string = "%s was reluctant to learn %s, but now he enjoys it."
     var format_string = "%s was reluctant to learn %s, but now he enjoys it."
     var actual_string = format_string % ["Estragon", "GDScript"]
     var actual_string = format_string % ["Estragon", "GDScript"]
-    
+
     print(actual_string)
     print(actual_string)
     # Output: "Estragon was reluctant to learn GDScript, but now he enjoys it."
     # Output: "Estragon was reluctant to learn GDScript, but now he enjoys it."
 
 

+ 1 - 1
getting_started/scripting/visual_script/getting_started.rst

@@ -3,7 +3,7 @@
 Getting started with Visual Scripting
 Getting started with Visual Scripting
 =====================================
 =====================================
 
 
-As with everything in Godot, we prioritize a good experience over copying or integrating third party solutions 
+As with everything in Godot, we prioritize a good experience over copying or integrating third party solutions
 which might not fit nicely in the current workflow. This led us to write our own version of how we believe
 which might not fit nicely in the current workflow. This led us to write our own version of how we believe
 this feature would work best with the engine.
 this feature would work best with the engine.
 
 

+ 2 - 2
getting_started/scripting/visual_script/index.rst

@@ -4,8 +4,8 @@ VisualScript
 .. toctree::
 .. toctree::
    :maxdepth: 3
    :maxdepth: 3
    :name: toc-learn-scripting-visual_script
    :name: toc-learn-scripting-visual_script
-   
+
    what_is_visual_scripting
    what_is_visual_scripting
    getting_started
    getting_started
    nodes_purposes
    nodes_purposes
-   
+

+ 21 - 21
getting_started/scripting/visual_script/nodes_purposes.rst

@@ -3,7 +3,7 @@
 Nodes and terminology
 Nodes and terminology
 =====================
 =====================
 
 
-Before continuing, it must be noted that the *Node* terminology needs to be used with care. 
+Before continuing, it must be noted that the *Node* terminology needs to be used with care.
 When referring to *Visual Script Nodes* (or generally *Nodes*) this text will refer to the little boxes you connect with lines, which are part of a graph.
 When referring to *Visual Script Nodes* (or generally *Nodes*) this text will refer to the little boxes you connect with lines, which are part of a graph.
 When referring to *Scene Nodes*, it is implied that the elements that make up a Scene are being referred, which are part of a tree. Their naming is similar but their function is different.
 When referring to *Scene Nodes*, it is implied that the elements that make up a Scene are being referred, which are part of a tree. Their naming is similar but their function is different.
 When referring to *Node* here, it will be implied that a *Visual Script Node* is referred to unless indicated otherwise.
 When referring to *Node* here, it will be implied that a *Visual Script Node* is referred to unless indicated otherwise.
@@ -15,7 +15,7 @@ Node properties
 ---------------
 ---------------
 
 
 Like in most visual scripting implementations, each node has editable properties. In Godot, though, we try to avoid
 Like in most visual scripting implementations, each node has editable properties. In Godot, though, we try to avoid
-bloating the nodes with editable controls for the sake of readability. 
+bloating the nodes with editable controls for the sake of readability.
 
 
 Nodes still display the required information as text, but editing is done via the *Inspector*. To edit them,
 Nodes still display the required information as text, but editing is done via the *Inspector*. To edit them,
 select any node and edit its properties in the *Inspector*.
 select any node and edit its properties in the *Inspector*.
@@ -24,29 +24,29 @@ select any node and edit its properties in the *Inspector*.
 Ports and connections
 Ports and connections
 ---------------------
 ---------------------
 
 
-Programming in Godot Visual Scripting is done via *Nodes* and *Port Connections* inside each function. 
+Programming in Godot Visual Scripting is done via *Nodes* and *Port Connections* inside each function.
 
 
 
 
 Ports
 Ports
 ~~~~~
 ~~~~~
 
 
-Nodes in Godot Visual Scripting have *Ports*. These are endpoints that appear to the 
+Nodes in Godot Visual Scripting have *Ports*. These are endpoints that appear to the
 left and right of nodes and which can be used to make *Connections*:
 left and right of nodes and which can be used to make *Connections*:
 There are two types of *Ports*: *Sequence* and *Data*.
 There are two types of *Ports*: *Sequence* and *Data*.
 
 
 .. image:: img/visual_script17.png
 .. image:: img/visual_script17.png
 
 
 
 
-*Sequence Ports* indicate the order in which operations are executed. 
-Typically when a *Node* is done processing, it will go to the next node from one of the ports at the right. 
-If nothing is connected the function may end, or another output *Sequence Port* might be tried (this depends on the node). 
+*Sequence Ports* indicate the order in which operations are executed.
+Typically when a *Node* is done processing, it will go to the next node from one of the ports at the right.
+If nothing is connected the function may end, or another output *Sequence Port* might be tried (this depends on the node).
 Thanks to this, you can follow the logic flow within a function by following the white lines.
 Thanks to this, you can follow the logic flow within a function by following the white lines.
 Not every *Node* has *Sequence Ports*. In fact, most do not.
 Not every *Node* has *Sequence Ports*. In fact, most do not.
 
 
-*Data Ports* ports contain typed values. Types can be any regular Godot types, 
-such as a boolean, an integer, a string, a Vector3, an array, any Object or Scene Node, etc. 
-A *Data Port* on the right side of a node is considered an output, while, 
-a port on the left side is an input. Connecting them allows information to flow to the next node. 
+*Data Ports* ports contain typed values. Types can be any regular Godot types,
+such as a boolean, an integer, a string, a Vector3, an array, any Object or Scene Node, etc.
+A *Data Port* on the right side of a node is considered an output, while,
+a port on the left side is an input. Connecting them allows information to flow to the next node.
 
 
 Not all *Data Port* types are compatible and will allow connections, though.
 Not all *Data Port* types are compatible and will allow connections, though.
 Pay special attention to colors and icons, as each type has a different representation:
 Pay special attention to colors and icons, as each type has a different representation:
@@ -57,19 +57,19 @@ Pay special attention to colors and icons, as each type has a different represen
 Connections
 Connections
 ~~~~~~~~~~~
 ~~~~~~~~~~~
 
 
-Connecting is a relatively simple process. Drag an *Output Port* towards an *Input Port*. 
+Connecting is a relatively simple process. Drag an *Output Port* towards an *Input Port*.
 
 
 .. image:: img/visual_script_connect.gif
 .. image:: img/visual_script_connect.gif
 
 
 
 
-Disconnecting takes a bit more practice. Disconnecting in *Data Ports* happens by 
+Disconnecting takes a bit more practice. Disconnecting in *Data Ports* happens by
 dragging the *Input* away, while for *Sequence Ports*, this happens by dragging the *Output* away.
 dragging the *Input* away, while for *Sequence Ports*, this happens by dragging the *Output* away.
 
 
 .. image:: img/visual_script_disconnect.gif
 .. image:: img/visual_script_disconnect.gif
 
 
 
 
-This may seem strange at the beginning, but it happens because *Data Ports* are 1:N 
-(A single output port can connect to many inputs), while *Sequence Ports* are N:1 
+This may seem strange at the beginning, but it happens because *Data Ports* are 1:N
+(A single output port can connect to many inputs), while *Sequence Ports* are N:1
 (Many sequence outputs can be connected to a single input).
 (Many sequence outputs can be connected to a single input).
 
 
 Connecting to empty space (drag to connect but unpress over empty space) is also context sensitive, it will supply
 Connecting to empty space (drag to connect but unpress over empty space) is also context sensitive, it will supply
@@ -86,7 +86,7 @@ While, for data, a contextual set/get/call menu will open:
 Adding nodes
 Adding nodes
 ------------
 ------------
 
 
-Finally! We got to the fun part! But, before explaining in more detail what each type of node does, 
+Finally! We got to the fun part! But, before explaining in more detail what each type of node does,
 let's take a short look at how nodes are most commonly added and dealt with.
 let's take a short look at how nodes are most commonly added and dealt with.
 
 
 
 
@@ -94,7 +94,7 @@ Accessing scene nodes
 ~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~
 
 
 One of the most common tasks is accessing Scene Tree Nodes (again, not to mistake with *Visual Script Nodes*).
 One of the most common tasks is accessing Scene Tree Nodes (again, not to mistake with *Visual Script Nodes*).
-Dragging from the Scene Tree and dropping into the canvas will ask you to *call a method* (sometimes referred to as *member function*) on this node. 
+Dragging from the Scene Tree and dropping into the canvas will ask you to *call a method* (sometimes referred to as *member function*) on this node.
 
 
 .. image:: img/visual_script19.png
 .. image:: img/visual_script19.png
 
 
@@ -210,7 +210,7 @@ a brief overview of node types follows:
 Constants
 Constants
 ~~~~~~~~~
 ~~~~~~~~~
 
 
-Constant nodes are nodes that provide values that, while not changing over time, can be useful as reference values. 
+Constant nodes are nodes that provide values that, while not changing over time, can be useful as reference values.
 Most of the time they are integer or float.
 Most of the time they are integer or float.
 
 
 .. image:: img/visual_script36.png
 .. image:: img/visual_script36.png
@@ -273,14 +273,14 @@ As it can be seen above, there are two nodes available: A simple getter, and a s
 Scene Node
 Scene Node
 ^^^^^^^^^^
 ^^^^^^^^^^
 
 
-This is just a reference to a node in the tree, but it's easier to use this node by dragging the actual node 
+This is just a reference to a node in the tree, but it's easier to use this node by dragging the actual node
 from the scene tree to the canvas (this will create it and configure it).
 from the scene tree to the canvas (this will create it and configure it).
 
 
 
 
 Self
 Self
 ^^^^
 ^^^^
 
 
-In some rare occasions, it may be desired to pass this Scene Node as argument. 
+In some rare occasions, it may be desired to pass this Scene Node as argument.
 It can be used to call functions and set/get properties, or drag nodes (or event the node itself that has the script) from the Scene Tree to the canvas for this.
 It can be used to call functions and set/get properties, or drag nodes (or event the node itself that has the script) from the Scene Tree to the canvas for this.
 
 
 
 
@@ -342,7 +342,7 @@ Some data types in Godot (ie, arrays, dictionaries) are iterable. This means tha
 for each element that it has.
 for each element that it has.
 
 
 The Iterator node goes through all elements and, for each of them, it goes via the "each" sequence port,
 The Iterator node goes through all elements and, for each of them, it goes via the "each" sequence port,
-making the element available in the "elem" data port. 
+making the element available in the "elem" data port.
 
 
 When done, it goes via the "exit" sequence port.
 When done, it goes via the "exit" sequence port.
 
 

+ 1 - 1
getting_started/step_by_step/intro_to_the_editor_interface.rst

@@ -115,7 +115,7 @@ Notice the text [perspective] under the toolbar, it is a button that opens a lis
 
 
 |image20|
 |image20|
 
 
-.. note:: Read :ref:`doc_introduction_to_3d` for more detail about **3D workspace**. 
+.. note:: Read :ref:`doc_introduction_to_3d` for more detail about **3D workspace**.
 
 
 The **Script** workspace is a complete code editor with a debugger, rich
 The **Script** workspace is a complete code editor with a debugger, rich
 auto-completion, and built-in code reference. Press F3 to access it, and
 auto-completion, and built-in code reference. Press F3 to access it, and

+ 9 - 9
getting_started/step_by_step/scripting.rst

@@ -70,11 +70,11 @@ F#, Boo or ClojureCLR. In practice however, C# is the only officially supported
 GDNative / C++
 GDNative / C++
 ~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~
 
 
-Finally, one of our brightest additions for the 3.0 release: 
+Finally, one of our brightest additions for the 3.0 release:
 GDNative allows scripting in C++ without needing to recompile (or even
 GDNative allows scripting in C++ without needing to recompile (or even
 restart) Godot.
 restart) Godot.
 
 
-Any C++ version can be used, and mixing compiler brands and versions for the 
+Any C++ version can be used, and mixing compiler brands and versions for the
 generated shared libraries works perfectly, thanks to our use of an internal C
 generated shared libraries works perfectly, thanks to our use of an internal C
 API Bridge.
 API Bridge.
 
 
@@ -182,7 +182,7 @@ signals in your own scripts.
 
 
 In this step, we'll connect the "pressed" signal to a custom function. Forming
 In this step, we'll connect the "pressed" signal to a custom function. Forming
 connections is the first part and defining the custom function is the second part.
 connections is the first part and defining the custom function is the second part.
-For the first part, Godot provides two ways to create connections: through a 
+For the first part, Godot provides two ways to create connections: through a
 visual interface the editor provides or through code.
 visual interface the editor provides or through code.
 
 
 While we will use the code method for the remainder of this tutorial series, let's
 While we will use the code method for the remainder of this tutorial series, let's
@@ -199,7 +199,7 @@ button in the bottom right, you'll open up the connection creation dialogue.
 .. image:: img/connect_dialogue.png
 .. image:: img/connect_dialogue.png
 
 
 In the bottom-left are the key things you need to create a connection: a node
 In the bottom-left are the key things you need to create a connection: a node
-which implements the method you want to trigger (represented here as a 
+which implements the method you want to trigger (represented here as a
 NodePath) and the name of the method to trigger.
 NodePath) and the name of the method to trigger.
 
 
 The top-left section displays a list of your scene's nodes with the emitting
 The top-left section displays a list of your scene's nodes with the emitting
@@ -246,7 +246,7 @@ Next, write a function which will be called when the button is pressed:
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
 
 
-    func _on_Button_pressed():  
+    func _on_Button_pressed():
         get_node("Label").text = "HELLO!"
         get_node("Label").text = "HELLO!"
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
@@ -323,7 +323,7 @@ Why, hello there! Congratulations on scripting your first scene.
 
 
     # Not for this case,
     # Not for this case,
     # but just in case.
     # but just in case.
-    get_node("Label/Button") 
+    get_node("Label/Button")
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
@@ -335,10 +335,10 @@ Also, remember that nodes are referenced by name, not by type.
 
 
 .. note::
 .. note::
 
 
-    The right-hand panel of the connect dialogue is for binding specific 
-    values to the connected function's parameters. You can add and remove 
+    The right-hand panel of the connect dialogue is for binding specific
+    values to the connected function's parameters. You can add and remove
     values of different types.
     values of different types.
 
 
     The code approach also enables this with a 4th ``Array`` parameter that
     The code approach also enables this with a 4th ``Array`` parameter that
-    is empty by default. Feel free to read up on the ``Object.connect`` 
+    is empty by default. Feel free to read up on the ``Object.connect``
     method for more information.
     method for more information.

+ 2 - 2
getting_started/workflow/assets/escn_exporter/animation.rst

@@ -7,9 +7,9 @@ Animation supported:
  - light animation
  - light animation
  - camera animation
  - camera animation
 
 
-Multiple Actions For Single Object 
+Multiple Actions For Single Object
 ----------------------------------
 ----------------------------------
-In most games, one objects would have several animations to switch between. 
+In most games, one objects would have several animations to switch between.
 This addon have a support for exporting multiple actions all at once into
 This addon have a support for exporting multiple actions all at once into
 a single AnimationPlayer and makes it easy to switch actions.
 a single AnimationPlayer and makes it easy to switch actions.
 
 

+ 1 - 1
getting_started/workflow/assets/escn_exporter/index.rst

@@ -1,7 +1,7 @@
 Godot-Blender-Exporter
 Godot-Blender-Exporter
 ======================
 ======================
 
 
-.. note:: This chapter relates to the blender plugin called "Godot-Blender-Exporter", 
+.. note:: This chapter relates to the blender plugin called "Godot-Blender-Exporter",
           which can be downloaded here: https://github.com/godotengine/godot-blender-exporter
           which can be downloaded here: https://github.com/godotengine/godot-blender-exporter
 
 
 Details on exporting
 Details on exporting

+ 1 - 1
getting_started/workflow/assets/escn_exporter/mesh.rst

@@ -4,7 +4,7 @@ Mesh
 Modifiers
 Modifiers
 ---------
 ---------
 There is an exporting option :code:`Apply Modifiers` to
 There is an exporting option :code:`Apply Modifiers` to
-control whether mesh modifiers are applied to the exported mesh. 
+control whether mesh modifiers are applied to the exported mesh.
 
 
 
 
 Shape Key
 Shape Key

+ 2 - 2
getting_started/workflow/assets/escn_exporter/skeleton.rst

@@ -7,9 +7,9 @@ Rest Bone
 ---------
 ---------
 
 
 Armature object in Blender is exported as a Skeleton node along with
 Armature object in Blender is exported as a Skeleton node along with
-rest position (transform in Godot) of bones. 
+rest position (transform in Godot) of bones.
 
 
-.. warning:: 
+.. warning::
     The three check boxes :code:`Inherit Rotation`, :code:`Inherit Scale`,
     The three check boxes :code:`Inherit Rotation`, :code:`Inherit Scale`,
     :code:`Local Location` (colored in red) must be ticked when building
     :code:`Local Location` (colored in red) must be ticked when building
     armature in Blender, so that the exported bone transform would be
     armature in Blender, so that the exported bone transform would be

+ 3 - 3
getting_started/workflow/assets/importing_audio_samples.rst

@@ -9,7 +9,7 @@ Why importing?
 Raw audio data in general is large and undesired. Godot provides two main
 Raw audio data in general is large and undesired. Godot provides two main
 options to import your audio data: WAV and OGG Vorbis.
 options to import your audio data: WAV and OGG Vorbis.
 
 
-Each has different advantages. 
+Each has different advantages.
 * Wav files use raw data or light compression, require small amount of CPU to play back (hundreds of simultaneous voices in this format are fine), but take up significant space.
 * Wav files use raw data or light compression, require small amount of CPU to play back (hundreds of simultaneous voices in this format are fine), but take up significant space.
 * Ogg Vorbis files use a stronger compression that results in much smaller file size, but uses significantly more processor to play back.
 * Ogg Vorbis files use a stronger compression that results in much smaller file size, but uses significantly more processor to play back.
 
 
@@ -49,10 +49,10 @@ As you can see above, sound effects become huge with reverb added.
 Trimming
 Trimming
 ~~~~~~~~
 ~~~~~~~~
 
 
-One issue that happens often is that the waveform are exported with long 
+One issue that happens often is that the waveform are exported with long
 silences at the beginning and at the end. These are inserted by
 silences at the beginning and at the end. These are inserted by
 DAWs when saving to a waveform, increase their size unnecessarily and
 DAWs when saving to a waveform, increase their size unnecessarily and
-add latency to the moment they are played back. 
+add latency to the moment they are played back.
 
 
 Importing as WAV with the Trimming option enabled solves
 Importing as WAV with the Trimming option enabled solves
 this.
 this.

+ 3 - 3
getting_started/workflow/assets/importing_images.rst

@@ -8,7 +8,7 @@ Why importing them?
 
 
 In Godot 3+, image files are no longer native resources and they must be imported.
 In Godot 3+, image files are no longer native resources and they must be imported.
 The reason behind this is the large amount of configuration parameters that
 The reason behind this is the large amount of configuration parameters that
-image files can be imported with. 
+image files can be imported with.
 
 
 This small tutorial will explain what these parameters are and how to best
 This small tutorial will explain what these parameters are and how to best
 make use of them.
 make use of them.
@@ -69,7 +69,7 @@ advantages and disadvantages ( |good| = Best, |bad| =Worst ):
 HDR Mode
 HDR Mode
 ~~~~~~~~
 ~~~~~~~~
 
 
-Godot supports high dynamic range textures (as .HDR or .EXR). These are mostly useful as high dynamic range equirectancular panorama skys (the internet 
+Godot supports high dynamic range textures (as .HDR or .EXR). These are mostly useful as high dynamic range equirectancular panorama skys (the internet
 has plenty of if you look for them), which replace Cubemaps in Godot 2.x. Modern PCs support the BC6H VRAM format, but there are still plenty that do not.
 has plenty of if you look for them), which replace Cubemaps in Godot 2.x. Modern PCs support the BC6H VRAM format, but there are still plenty that do not.
 
 
 If you want Godot to ensure full compatibility in for kind of textures, enable the "Force RGBE" option.
 If you want Godot to ensure full compatibility in for kind of textures, enable the "Force RGBE" option.
@@ -108,7 +108,7 @@ When pixels become smaller than the screen, mipmaps kick in. This helps reduce t
 * Texture width and height must be powers of 2
 * Texture width and height must be powers of 2
 * Repeat must be enabled
 * Repeat must be enabled
 
 
-Keep in mind the above when making phone games and applications, want to aim for full compatibility, and need mipmaps. 
+Keep in mind the above when making phone games and applications, want to aim for full compatibility, and need mipmaps.
 
 
 When doing 3D, mipmap should be turned on as this also improves performance (smaller versions of the texture are used for objects further away).
 When doing 3D, mipmap should be turned on as this also improves performance (smaller versions of the texture are used for objects further away).
 
 

+ 8 - 8
getting_started/workflow/assets/importing_scenes.rst

@@ -11,7 +11,7 @@ When dealing with 3D assets, Godot has a flexible and configurable importer.
 Godot works with *scenes*. This means that the entire scene being worked on in your favorite 3D DCC will be
 Godot works with *scenes*. This means that the entire scene being worked on in your favorite 3D DCC will be
 transferred as close as possible.
 transferred as close as possible.
 
 
-Godot supports the following 3D *scene file fomats*: 
+Godot supports the following 3D *scene file fomats*:
 
 
 * DAE (Collada), which is currently the most mature workflow.
 * DAE (Collada), which is currently the most mature workflow.
 * GLTF 2.0. Both text and binary formats are supported. Godot has full support for it, but the format is new and gaining traction.
 * GLTF 2.0. Both text and binary formats are supported. Godot has full support for it, but the format is new and gaining traction.
@@ -25,7 +25,7 @@ Why not FBX?
 Most game engines use the FBX format for importing 3D scenes, which is
 Most game engines use the FBX format for importing 3D scenes, which is
 definitely one of the most standardized in the industry. However, this
 definitely one of the most standardized in the industry. However, this
 format requires the use of a closed library from Autodesk which is
 format requires the use of a closed library from Autodesk which is
-distributed with a more restrictive licensing terms than Godot. 
+distributed with a more restrictive licensing terms than Godot.
 
 
 The plan is, sometime in the future, to offer a binary plug-in using GDNative.
 The plan is, sometime in the future, to offer a binary plug-in using GDNative.
 
 
@@ -53,7 +53,7 @@ Exporting ESCN files from Blender
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 The most powerful one, called `godot-blender-exporter
 The most powerful one, called `godot-blender-exporter
-<https://github.com/godotengine/godot-blender-exporter>`__. 
+<https://github.com/godotengine/godot-blender-exporter>`__.
 It uses .escn files which is kind of another name of .tscn file(Godot scene file),
 It uses .escn files which is kind of another name of .tscn file(Godot scene file),
 it keeps as much information as possible from a Blender scene.
 it keeps as much information as possible from a Blender scene.
 
 
@@ -99,7 +99,7 @@ Allows setting a specific name to the generated root node.
 Custom Script
 Custom Script
 ^^^^^^^^^^^^^
 ^^^^^^^^^^^^^
 
 
-A special script to process the whole scene after import can be provided. 
+A special script to process the whole scene after import can be provided.
 This is great for post processing, changing materials, doing funny stuff
 This is great for post processing, changing materials, doing funny stuff
 with the geometry etc.
 with the geometry etc.
 
 
@@ -123,12 +123,12 @@ Storage
 
 
 By default, Godot imports a single scene. This option allows specifying
 By default, Godot imports a single scene. This option allows specifying
 that nodes below the root will each be a separate scene and instanced
 that nodes below the root will each be a separate scene and instanced
-into the imported one. 
+into the imported one.
 
 
 Of course, instancing such imported scenes in other places manually works too.
 Of course, instancing such imported scenes in other places manually works too.
 
 
 
 
-Materials 
+Materials
 ~~~~~~~~~
 ~~~~~~~~~
 
 
 Location
 Location
@@ -262,7 +262,7 @@ following dialog will appear:
 
 
 .. image:: img/scene_import4.png
 .. image:: img/scene_import4.png
 
 
-In inherited scenes, the only limitations for modifications are: 
+In inherited scenes, the only limitations for modifications are:
 
 
 * Nodes can't be removed (but can be added anywhere).
 * Nodes can't be removed (but can be added anywhere).
 * Sub-Resources can't be edited (save them externally as described above for this)
 * Sub-Resources can't be edited (save them externally as described above for this)
@@ -295,7 +295,7 @@ Option "-col" will work only for Mesh nodes. If it is detected, a child
 static collision node will be added, using the same geometry as the mesh.
 static collision node will be added, using the same geometry as the mesh.
 
 
 However, it is often the case that the visual geometry is too complex or
 However, it is often the case that the visual geometry is too complex or
-too un-smooth for collisions, which ends up not working well. 
+too un-smooth for collisions, which ends up not working well.
 
 
 To solve this, the "-colonly" modifier exists, which will remove the mesh upon
 To solve this, the "-colonly" modifier exists, which will remove the mesh upon
 import and create a :ref:`class_staticbody` collision instead.
 import and create a :ref:`class_staticbody` collision instead.

+ 19 - 19
getting_started/workflow/export/exporting_for_ios.rst

@@ -3,8 +3,8 @@
 Exporting for iOS
 Exporting for iOS
 =================
 =================
 
 
-These are the steps to load a Godot project in Xcode. This allows you to 
-build and deploy to an iOS device, build a release for the App Store, and 
+These are the steps to load a Godot project in Xcode. This allows you to
+build and deploy to an iOS device, build a release for the App Store, and
 do everything else you can normally do with Xcode.
 do everything else you can normally do with Xcode.
 
 
 Requirements
 Requirements
@@ -17,10 +17,10 @@ Requirements
 Export a Godot project to Xcode
 Export a Godot project to Xcode
 -------------------------------
 -------------------------------
 
 
-In the Godot editor, open the **Export** window from the **Project** menu. When the 
-Export window opens, click **Add..** and select **iOS**. 
+In the Godot editor, open the **Export** window from the **Project** menu. When the
+Export window opens, click **Add..** and select **iOS**.
 
 
-The following export options are required. Leaving any blank with cause the 
+The following export options are required. Leaving any blank with cause the
 exporter to throw an error:
 exporter to throw an error:
 
 
   * In the **Application** category
   * In the **Application** category
@@ -31,42 +31,42 @@ exporter to throw an error:
 
 
 After you click **Export Project**, there are still two important options left:
 After you click **Export Project**, there are still two important options left:
 
 
-  * **Path** is an empty folder that will contain the exported Xcode project files. 
-  * **File** will be the name of the Xcode project and several project specific files and directories.  
+  * **Path** is an empty folder that will contain the exported Xcode project files.
+  * **File** will be the name of the Xcode project and several project specific files and directories.
 
 
 .. image:: img/ios_export_file.png
 .. image:: img/ios_export_file.png
 
 
 .. note:: This tutorial uses **exported_xcode_project_name**, but you will use your
 .. note:: This tutorial uses **exported_xcode_project_name**, but you will use your
-          project's name. When you see **exported_xcode_project_name** 
-          in the following steps, replace it with the name you used instead. 
+          project's name. When you see **exported_xcode_project_name**
+          in the following steps, replace it with the name you used instead.
 
 
 When the export completes, the output folder should look like this:
 When the export completes, the output folder should look like this:
 
 
 .. image:: img/ios_export_output.png
 .. image:: img/ios_export_output.png
 
 
-Opening **exported_xcode_project_name.xcodeproj** lets you build and deploy 
-like any other iOS app. 
+Opening **exported_xcode_project_name.xcodeproj** lets you build and deploy
+like any other iOS app.
 
 
 
 
 Active development considerations
 Active development considerations
 ---------------------------------
 ---------------------------------
 
 
 The above method creates an exported project that you can build for
 The above method creates an exported project that you can build for
-release, but you have to re-export every time you make a change in Godot. 
+release, but you have to re-export every time you make a change in Godot.
 
 
 While developing, you can speed this process up by linking your
 While developing, you can speed this process up by linking your
-Godot project files directly into your app. 
+Godot project files directly into your app.
 
 
 In the following example:
 In the following example:
 
 
-  * **exported_xcode_project_name** is the name of the exported iOS application (as above). 
-  * **godot_project_to_export** is the name of the Godot project. 
+  * **exported_xcode_project_name** is the name of the exported iOS application (as above).
+  * **godot_project_to_export** is the name of the Godot project.
 
 
 Steps to link an Godot project folder to Xcode
 Steps to link an Godot project folder to Xcode
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
 1. Start from an exported iOS project (follow the steps above).
 1. Start from an exported iOS project (follow the steps above).
-2. In Finder, drag the Godot project folder into the Xcode file browser. 
+2. In Finder, drag the Godot project folder into the Xcode file browser.
 
 
 .. image:: img/ios_export_add_dir.png
 .. image:: img/ios_export_add_dir.png
 
 
@@ -75,19 +75,19 @@ you will be able to continue to edit your Godot project in its current location.
 
 
 .. image:: img/ios_export_file_ref.png
 .. image:: img/ios_export_file_ref.png
 
 
-4. See the **godot_project_to_export** folder in the Xcode file browser. 
+4. See the **godot_project_to_export** folder in the Xcode file browser.
 5. Delete **exported_xcode_project_name.pck** from the Xcode project.
 5. Delete **exported_xcode_project_name.pck** from the Xcode project.
 
 
 .. image:: img/ios_export_delete_pck.png
 .. image:: img/ios_export_delete_pck.png
 
 
 6. Open **exported_xcode_project_name-Info.plist** and add a string property named
 6. Open **exported_xcode_project_name-Info.plist** and add a string property named
-**godot_path** (this is the real key name) with a value **godot_project_to_export** 
+**godot_path** (this is the real key name) with a value **godot_project_to_export**
 (this is the name of your project)
 (this is the name of your project)
 
 
 .. image:: img/ios_export_set_path.png
 .. image:: img/ios_export_set_path.png
 
 
 That's it! You can now edit your project in the Godot editor and build it
 That's it! You can now edit your project in the Godot editor and build it
-in Xcode when you want to run it on a device. 
+in Xcode when you want to run it on a device.
 
 
 Services for iOS
 Services for iOS
 ----------------
 ----------------

+ 1 - 1
getting_started/workflow/export/exporting_for_uwp.rst

@@ -28,7 +28,7 @@ As described in `UWP documentation <https://docs.microsoft.com/en-us/windows/uwp
     - available memory is 5GB
     - available memory is 5GB
     - 4 exclusive CPU cores and 2 shared CPU cores
     - 4 exclusive CPU cores and 2 shared CPU cores
     - exclusive access to GPU power (100%)
     - exclusive access to GPU power (100%)
-    
+
 - Exceeding these memory limitations will cause allocation failures and the application will crash.
 - Exceeding these memory limitations will cause allocation failures and the application will crash.
 
 
 Creating a signing certificate
 Creating a signing certificate

+ 1 - 1
getting_started/workflow/export/index.rst

@@ -5,7 +5,7 @@ Export
    :maxdepth: 1
    :maxdepth: 1
    :name: toc-learn-workflow-export
    :name: toc-learn-workflow-export
 
 
- 
+
    exporting_projects
    exporting_projects
    feature_tags
    feature_tags
    exporting_for_pc
    exporting_for_pc

+ 72 - 72
tutorials/2d/2d_lights_and_shadows.rst

@@ -6,7 +6,7 @@
 Introduction
 Introduction
 ------------
 ------------
 
 
-This tutorial explains how the 2D lighting works in the 
+This tutorial explains how the 2D lighting works in the
 `lights and shadows <https://github.com/godotengine/godot-demo-projects/tree/master/2d/lights_and_shadows>`_ demo project.
 `lights and shadows <https://github.com/godotengine/godot-demo-projects/tree/master/2d/lights_and_shadows>`_ demo project.
 It begins with a brief description of the resources used final demo and then describes how
 It begins with a brief description of the resources used final demo and then describes how
 to make a scene like the demo step by step.
 to make a scene like the demo step by step.
@@ -14,31 +14,31 @@ to make a scene like the demo step by step.
 .. image:: img/light_shadow_main.png
 .. image:: 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>`_
 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, 
-it can be downloaded from the Project Manager. Launch Godot and in the top 
+on github. I suggest you download it before starting. Alternatively,
+it can be downloaded from the Project Manager. Launch Godot and in the top
 bar select "Templates" and search for "2D Lights and Shadows Demo".
 bar select "Templates" and search for "2D Lights and Shadows Demo".
 
 
 Setup
 Setup
 -----
 -----
 
 
-For this demo we use four textures: two for the lights, one for the shadow casters, 
+For this demo we use four textures: two for the lights, one for the shadow casters,
 and one for the background. I've included links to them all here if you want to download them
 and one for the background. I've included links to them all here if you want to download them
 separately from the demo.
 separately from the demo.
 
 
-The first is the background image (`bg.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/bg.png>`_) 
+The first is the background image (`bg.png <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/bg.png>`_)
 used in the demo. You do not necessarily need a background, but we use one for the demo.
 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>`_) 
-to use as our shadow caster object. For a top down game this could be a wall or any 
+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.
 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>`_). 
-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 
+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.
 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>`_). 
-The demo uses a blob to show where the light is and the larger light 
+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.
 image to show the effect of the light upon the rest of the scene.
 
 
 
 
@@ -51,24 +51,24 @@ The demo uses four different nodes:
   * :ref:`Light2D <class_Light2D>`
   * :ref:`Light2D <class_Light2D>`
   * :ref:`LightOccluder2D <class_LightOccluder2D>`
   * :ref:`LightOccluder2D <class_LightOccluder2D>`
 
 
-:ref:`CanvasModulate<class_CanvasModulate>` is used to darken the scene. 
+:ref:`CanvasModulate<class_CanvasModulate>` is used to darken the scene.
 
 
-:ref:`Sprites <class_Sprite>` are used to display the textures for the light blobs, the 
+:ref:`Sprites <class_Sprite>` are used to display the textures for the light blobs, the
 background, and for the shadow casters.
 background, and for the shadow casters.
 
 
-:ref:`Light2Ds <class_Light2D>` are used to light the scene. The way a light typically works 
+:ref:`Light2Ds <class_Light2D>` are used to light the scene. The way a light typically works
 is by adding a selected texture over the rest of the scene to simulate lighting. But it can be
 is by adding a selected texture over the rest of the scene to simulate lighting. But it can be
 used in other ways, for example masking out parts of the scene.
 used in other ways, for example masking out parts of the scene.
 
 
-:ref:`LightOccluder2Ds <class_LightOccluder2D>` are used to tell the shader which parts of 
-the scene cast shadows. The shadows appear only on areas covered by the :ref:`Light2D <class_Light2D>` and 
+:ref:`LightOccluder2Ds <class_LightOccluder2D>` are used to tell the shader which parts of
+the scene cast shadows. The shadows appear only on areas covered by the :ref:`Light2D <class_Light2D>` and
 their direction is based on the center of the :ref:`Light <class_Light2D>`.
 their direction is based on the center of the :ref:`Light <class_Light2D>`.
 
 
 Lights
 Lights
 ------
 ------
 
 
-:ref:`Lights <class_Light2D>` cover the entire extent of their respective Texture. They use additive 
-blending to add the color of their texture to the scene. 
+:ref:`Lights <class_Light2D>` 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
 .. image:: img/light_shadow_light.png
 
 
@@ -81,12 +81,12 @@ blending to add the color of their texture to the scene.
 ``Mix`` mixes the color of the light with the underlying scene. The resulting brightness is
 ``Mix`` mixes the color of the light with the underlying scene. The resulting brightness is
 halfway between the color of the light and the color underneath.
 halfway between the color of the light and the color underneath.
 
 
-``Mask`` is used to mask out areas that are covered by the light. Masked out areas are hidden or revealed based on 
+``Mask`` is used to mask out areas that are covered by the light. Masked out areas are hidden or revealed based on
 the color of the light.
 the color of the light.
 
 
-For the demo the lights have two components, the :ref:`Light <class_Light2D>` itself (which 
-is the effect of the light), and a :ref:`Sprite <class_Sprite>` blob which is an image showing the 
-location of the light source. A child :ref:`Sprite <class_Sprite>` is not necessary to make a 
+For the demo the lights have two components, the :ref:`Light <class_Light2D>` itself (which
+is the effect of the light), and a :ref:`Sprite <class_Sprite>` blob which is an image showing the
+location of the light source. A child :ref:`Sprite <class_Sprite>` is not necessary to make a
 :ref:`Light <class_Light2D>` work.
 :ref:`Light <class_Light2D>` work.
 
 
 .. image:: img/light_shadow_light_blob.png
 .. image:: img/light_shadow_light_blob.png
@@ -96,82 +96,82 @@ Shadows
 
 
 Shadows are made by intersecting a :ref:`Light <class_Light2D>` with a :ref:`LightOccluder2D <class_LightOccluder2D>`.
 Shadows are made by intersecting a :ref:`Light <class_Light2D>` with a :ref:`LightOccluder2D <class_LightOccluder2D>`.
 
 
-By default shadows are turned off. To turn them on click on the :ref:`Light <class_Light2D>` 
+By default shadows are turned off. To turn them on click on the :ref:`Light <class_Light2D>`
 and under the Shadows section check ``Enabled``.
 and under the Shadows section check ``Enabled``.
 
 
-In the demo we are using a :ref:`Sprite <class_Sprite>` with a Texture on it to make the "Shadow Casters", 
-but in reality all you need is a couple of :ref:`LightOccluder2Ds <class_LightOccluder2D>`. By itself 
-the :ref:`LightOccluder2D <class_LightOccluder2D>` looks like a dark spot and in this demo the :ref:`Sprite <class_Sprite>` is 
+In the demo we are using a :ref:`Sprite <class_Sprite>` with a Texture on it to make the "Shadow Casters",
+but in reality all you need is a couple of :ref:`LightOccluder2Ds <class_LightOccluder2D>`. By itself
+the :ref:`LightOccluder2D <class_LightOccluder2D>` looks like a dark spot and in this demo the :ref:`Sprite <class_Sprite>` is
 just a black square.
 just a black square.
 
 
 Step by step
 Step by step
 ------------
 ------------
 
 
-Now that we have covered the basics of the nodes being used, we can now walk step by step through 
+Now that we have covered the basics of the nodes being used, we can now walk step by step through
 the process of making a scene like the one found in the demo.
 the process of making a scene like the one found in the demo.
 
 
-First add a :ref:`Sprite <class_Sprite>` and set its texture to the `background image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/bg.png>`_. For your game this can be any 
-background you choose. For this style of shadow it is most likely to be a floor texture. 
+First add a :ref:`Sprite <class_Sprite>` and set its texture to the `background image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/bg.png>`_. 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
 .. image:: img/light_shadow_background.png
 
 
-Next create three :ref:`Light2D's <class_Light2D>` and set their textures to the `light image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/light.png>`_. You can alter their 
-color in the top section. By default shadows are turned off and the ``mode`` is set to ``add``. This 
+Next create three :ref:`Light2D's <class_Light2D>` and set their textures to the `light image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/light.png>`_. 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.
 means that each light adds its own color to whatever is underneath.
 
 
 .. image:: img/light_shadow_all_lights_no_blob.png
 .. image:: img/light_shadow_all_lights_no_blob.png
 
 
-Next add a child :ref:`Sprite <class_Sprite>` to each of the :ref:`Light <class_Light2D>` nodes, and set 
-the :ref:`Sprite's <class_Sprite>` texture to the `blob image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/spot.png>`_. Each of these 
-should stay centered on the :ref:`Light <class_Light2D>` node. The blob is the image of the light 
-itself while the :ref:`Light <class_Light2D>` shows the effect that the light has on the scene. The 
-:ref:`LightOccluder2D's <class_LightOccluder2D>` will treat the position of the light as the center of the :ref:`Light <class_Light2D>` 
+Next add a child :ref:`Sprite <class_Sprite>` to each of the :ref:`Light <class_Light2D>` nodes, and set
+the :ref:`Sprite's <class_Sprite>` texture to the `blob image <https://raw.githubusercontent.com/godotengine/godot-demo-projects/master/2d/lights_and_shadows/spot.png>`_. Each of these
+should stay centered on the :ref:`Light <class_Light2D>` node. The blob is the image of the light
+itself while the :ref:`Light <class_Light2D>` shows the effect that the light has on the scene. The
+:ref:`LightOccluder2D's <class_LightOccluder2D>` will treat the position of the light as the center of the :ref:`Light <class_Light2D>`
 node which is why we want the blob to be centered on its parent :ref:`Light <class_Light2D>`.
 node which is why we want the blob to be centered on its parent :ref:`Light <class_Light2D>`.
 
 
 .. image:: img/light_shadow_all_lights.png
 .. image:: img/light_shadow_all_lights.png
 
 
-.. note:: At the time of writing, 3.0 is the stable release version. The 3.1 development branch contains 
-          many changes to the animation system, so the animations in the demo will not be covered here. 
+.. note:: At the time of writing, 3.0 is the stable release version. The 3.1 development branch contains
+          many changes to the animation system, so the animations in the demo will not be covered here.
           See :ref:Introduction to 2D Animation. <doc_introduction_2d> for more information.
           See :ref:Introduction to 2D Animation. <doc_introduction_2d> for more information.
 
 
-Right now the scene should look too bright. This is because all three lights are adding color to the scene. 
+Right now the scene should look too bright. This is because all three lights are adding color to the scene.
 This is why the demo uses a :ref:`CanvasModulate <class_CanvasModulate>` in the scene. The
 This is why the demo uses a :ref:`CanvasModulate <class_CanvasModulate>` in the scene. The
 :ref:`CanvasModulate <class_CanvasModulate>` multiples the entire viewport by a specific color.
 :ref:`CanvasModulate <class_CanvasModulate>` multiples the entire viewport by a specific color.
 
 
-Add a :ref:`CanvasModulate <class_CanvasModulate>` to the scene and set its color to ``rgb(70, 70, 70)``. 
+Add a :ref:`CanvasModulate <class_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.
 This will make the scene sufficiently dark to see the effects of the lights distinctly.
 
 
 .. image:: img/light_shadow_ambient.png
 .. image:: img/light_shadow_ambient.png
 
 
 Now we add the shadow casters.
 Now we add the shadow casters.
 
 
-The demo uses a :ref:`Node <class_Node2D>` named "casters" to organize the shadow casters. Add a 
-:ref:`Node2D <class_Node2D>` to the scene. It will be used to group all the shadow casters together. 
+The demo uses a :ref:`Node <class_Node2D>` named "casters" to organize the shadow casters. Add a
+:ref:`Node2D <class_Node2D>` to the scene. It will be used to group all the shadow casters together.
 This way we can show and hide them all at the same time.
 This way we can show and hide them all at the same time.
 
 
-Each shadow caster is made of a :ref:`Sprite <class_Sprite>`, with a :ref:`LightOccluder2D <class_LightOccluder2D>` 
-child. For the demo the :ref:`Sprite <class_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 :ref:`LightOccluder2D <class_LightOccluder2D>` is where all the magic happens. In a 
-game the :ref:`Sprite <class_Sprite>` could be more than a black box; it could be an image of whatever object is casting 
+Each shadow caster is made of a :ref:`Sprite <class_Sprite>`, with a :ref:`LightOccluder2D <class_LightOccluder2D>`
+child. For the demo the :ref:`Sprite <class_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 :ref:`LightOccluder2D <class_LightOccluder2D>` is where all the magic happens. In a
+game the :ref:`Sprite <class_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.
 the shadow: a wall, a magical chest, or anything else.
 
 
 .. image:: img/light_shadow_sprites.png
 .. image:: img/light_shadow_sprites.png
 
 
-:ref:`LightOccluder2Ds <class_LightOccluder2D>` tell the game what shape the occluder has. They hold 
-an :ref:`OccluderPolygon2D <class_OccluderPolygon2D>` which is a container 
-for a polygon and some other information. For this demo, since our wall is a square, we 
+:ref:`LightOccluder2Ds <class_LightOccluder2D>` tell the game what shape the occluder has. They hold
+an :ref:`OccluderPolygon2D <class_OccluderPolygon2D>` which is a container
+for a polygon and some other information. For this demo, since our wall is a square, we
 set ``Polygon`` to a square. The other default settings are fine.
 set ``Polygon`` to a square. The other default settings are fine.
 
 
-The first setting, ``Closed`` can be either ``on`` or ``off``. A closed polygon occludes light 
+The first setting, ``Closed`` can be either ``on`` or ``off``. A closed polygon occludes light
 coming from all directions. An open polygon only occludes light from one direction
 coming from all directions. An open polygon only occludes light from one direction
 
 
-``Cull Mode`` lets you select which direction gets culled. The default is ``Disabled``, meaning the occluder 
-will cast a shadow no matter which side the light is on. The other two settings ``Clockwise`` and 
-``Counter-Clockwise`` refer to the winding order of the vertices of the polygon. The winding order 
-is used to determine which side of the line is inside the polygon. Only outward facing lines cast shadows. 
+``Cull Mode`` lets you select which direction gets culled. The default is ``Disabled``, meaning the occluder
+will cast a shadow no matter which side the light is on. The other two settings ``Clockwise`` and
+``Counter-Clockwise`` refer to the winding order of the vertices of the polygon. The winding order
+is used to determine which side of the line is inside the polygon. Only outward facing lines cast shadows.
 
 
 To illustrate the difference, here is an image of a :ref:`LightOccluder2D <class_LightOccluder2D>` with ``Closed``
 To illustrate the difference, here is an image of a :ref:`LightOccluder2D <class_LightOccluder2D>` with ``Closed``
-set to ``off`` in the corresponding :ref:`OccluderPolygon2D <class_OccluderPolygon2D>` so that the 
+set to ``off`` in the corresponding :ref:`OccluderPolygon2D <class_OccluderPolygon2D>` so that the
 lines of the polygon can be seen:
 lines of the polygon can be seen:
 
 
 .. image:: img/light_shadow_cull_disabled.png
 .. image:: img/light_shadow_cull_disabled.png
@@ -188,18 +188,18 @@ lines of the polygon can be seen:
           If ``Closed`` was set to ``on`` there would be an additional vertical line on the
           If ``Closed`` was set to ``on`` there would be an additional vertical line on the
           left which would cast a shadow as well.
           left which would cast a shadow as well.
 
 
-When you have added the :ref:`LightOccluder2Ds <class_LightOccluder2D>` the shadows still won't 
-appear. You need to go back into the :ref:`Light2Ds <class_Light2D>` and under the Shadow 
+When you have added the :ref:`LightOccluder2Ds <class_LightOccluder2D>` the shadows still won't
+appear. You need to go back into the :ref:`Light2Ds <class_Light2D>` and under the Shadow
 section set ``Enable`` to ``on``. This turns on shadows with hard edges like in the image below.
 section set ``Enable`` to ``on``. This turns on shadows with hard edges like in the image below.
 
 
 .. image:: img/light_shadow_filter0_pcf0.png
 .. image:: 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>`_ 
-(PCF) which takes multiple samples of the shadow map around a pixel and blurs them to create 
-a smooth shadow effect. The higher the number of samples the smoother the shadow will 
-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. 
+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>`_
+(PCF) which takes multiple samples of the shadow map around a pixel and blurs them to create
+a smooth shadow effect. The higher the number of samples the smoother the shadow will
+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
 .. image:: img/light_shadow_normal.png
 
 
@@ -208,27 +208,27 @@ The demo uses PCF7.
 
 
 .. image:: img/light_shadow_pcf13.png
 .. image:: img/light_shadow_pcf13.png
 
 
-.. note:: ``filter`` is set to ``PCF13``. Notice how the shadow becomes wider, this is because the 
+.. 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``.
           distance between samples is based on the variable ``filter smooth``.
 
 
-In order to make use of filtering you need to set the ``filter smooth`` variable. 
-This dictates how far apart the samples are. If you want the soft area to extend quite far you can increase 
-the size of ``filter smooth``. However with low samples and a large filter smooth you can see lines 
+In order to make use of filtering you need to set the ``filter smooth`` variable.
+This dictates how far apart the samples are. If you want the soft area to extend quite far you can increase
+the size of ``filter smooth``. However with low samples and a large filter smooth you can see lines
 forming between the samples.
 forming between the samples.
 
 
 .. image:: img/light_shadow_filter30.png
 .. image:: img/light_shadow_filter30.png
 
 
 .. note:: ``filter smooth` is set to ``30``.
 .. note:: ``filter smooth` is set to ``30``.
 
 
-The different :ref:`Light <class_Light2D>` nodes in the demo use different values for filter smooth. 
+The different :ref:`Light <class_Light2D>` nodes in the demo use different values for filter smooth.
 Play around with it and see what you like.
 Play around with it and see what you like.
 
 
 .. image:: img/light_shadow_filter0.png
 .. image:: img/light_shadow_filter0.png
 
 
 .. note:: ``filter smooth`` is set to ``0``.
 .. note:: ``filter smooth`` is set to ``0``.
 
 
-Lastly there is the variable ``gradient length``. For some smooth shadows it is preferable to not have the 
-shadow start immediately on the object as this produces a hard edge. The gradient length variable creates 
+Lastly there is the variable ``gradient length``. For some smooth shadows it is preferable to not have the
+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.
 a smooth gradient to begin the shadow to reduce the effect of the hard edge.
 
 
 .. image:: img/light_shadow_grad0.png
 .. image:: img/light_shadow_grad0.png
@@ -240,5 +240,5 @@ a smooth gradient to begin the shadow to reduce the effect of the hard edge.
 .. note:: ``gradient length`` is set to ``10``.
 .. note:: ``gradient length`` is set to ``10``.
 
 
 You will need to play around with settings a bit to find ones that suit your project. There is no right solution
 You will need to play around with settings a bit to find ones that suit your project. There is no right solution
-for everyone, which is why Godot provides so much flexibility. Just keep in mind that the higher ``filter`` 
+for everyone, which is why Godot provides so much flexibility. Just keep in mind that the higher ``filter``
 set the more expensive the shadows will be.
 set the more expensive the shadows will be.

+ 10 - 10
tutorials/2d/2d_movement.rst

@@ -123,7 +123,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
-    
+
     extends KinematicBody2D
     extends KinematicBody2D
 
 
     export (int) var speed = 200
     export (int) var speed = 200
@@ -148,7 +148,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
         get_input()
         get_input()
         rotation += rotation_dir * rotation_speed * delta
         rotation += rotation_dir * rotation_speed * delta
         move_and_slide(velocity)
         move_and_slide(velocity)
-        
+
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
     using Godot;
     using Godot;
@@ -192,7 +192,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
             MoveAndSlide(velocity);
             MoveAndSlide(velocity);
         }
         }
     }
     }
-        
+
 Here we've added two new variables to track our rotation direction and speed.
 Here we've added two new variables to track our rotation direction and speed.
 Again, pressing both keys at once will cancel out and result in no rotation.
 Again, pressing both keys at once will cancel out and result in no rotation.
 The rotation is applied directly to the body's ``rotation`` property.
 The rotation is applied directly to the body's ``rotation`` property.
@@ -213,7 +213,7 @@ is set by the mouse position instead of the keyboard. The character will always
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
-    
+
     extends KinematicBody2D
     extends KinematicBody2D
 
 
     export (int) var speed = 200
     export (int) var speed = 200
@@ -271,7 +271,7 @@ could get the same effect by setting the angle like this:
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
-    
+
     rotation = get_global_mouse_position().angle_to_point(position)
     rotation = get_global_mouse_position().angle_to_point(position)
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
@@ -289,7 +289,7 @@ on the screen will cause the player to move to the target location.
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
-    
+
     extends KinematicBody2D
     extends KinematicBody2D
 
 
     export (int) var speed = 200
     export (int) var speed = 200
@@ -306,7 +306,7 @@ on the screen will cause the player to move to the target location.
         # rotation = velocity.angle()
         # rotation = velocity.angle()
         if (target - position).length() > 5:
         if (target - position).length() > 5:
             move_and_slide(velocity)
             move_and_slide(velocity)
-            
+
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
     using Godot;
     using Godot;
@@ -337,19 +337,19 @@ on the screen will cause the player to move to the target location.
             }
             }
         }
         }
     }
     }
-            
+
 
 
 Note the ``length()`` check we make prior to movement. Without this test,
 Note the ``length()`` check we make prior to movement. Without this test,
 the body would "jitter" upon reaching the target position, as it moves
 the body would "jitter" upon reaching the target position, as it moves
 slightly past the position and tries to move back, only to move too far and
 slightly past the position and tries to move back, only to move too far and
-repeat. 
+repeat.
 
 
 Uncommenting the ``rotation`` line will also turn the body to point in its
 Uncommenting the ``rotation`` line will also turn the body to point in its
 direction of motion if you prefer.
 direction of motion if you prefer.
 
 
 .. tip:: This technique can also be used as the basis of a "following" character.
 .. tip:: This technique can also be used as the basis of a "following" character.
          The ``target`` position can be that of any object you want to move to.
          The ``target`` position can be that of any object you want to move to.
-         
+
 Summary
 Summary
 -------
 -------
 
 

+ 87 - 87
tutorials/3d/fps_tutorial/part_five.rst

@@ -12,7 +12,7 @@ In this part we're going to add grenades to the player, give the player the abil
 
 
 .. note:: You are assumed to have finished :ref:`doc_fps_tutorial_part_four` before moving on to this part of the tutorial.
 .. note:: You are assumed to have finished :ref:`doc_fps_tutorial_part_four` before moving on to this part of the tutorial.
           The finished project from :ref:`doc_fps_tutorial_part_four` will be the starting project for part 5
           The finished project from :ref:`doc_fps_tutorial_part_four` will be the starting project for part 5
-          
+
 Let's get started!
 Let's get started!
 
 
 Adding grenades
 Adding grenades
@@ -34,7 +34,7 @@ coordinates instead of local coordinates, so we have ``Local Coords`` unchecked
 Let's write the code needed for the grenade. Select ``Grenade`` and make a new script called ``Grenade.gd``. Add the following:
 Let's write the code needed for the grenade. Select ``Grenade`` and make a new script called ``Grenade.gd``. Add the following:
 
 
 ::
 ::
-    
+
     extends RigidBody
     extends RigidBody
 
 
     const GRENADE_DAMAGE = 60
     const GRENADE_DAMAGE = 60
@@ -55,35 +55,35 @@ Let's write the code needed for the grenade. Select ``Grenade`` and make a new s
         grenade_mesh = $Grenade
         grenade_mesh = $Grenade
         blast_area = $Blast_Area
         blast_area = $Blast_Area
         explosion_particles = $Explosion
         explosion_particles = $Explosion
-        
+
         explosion_particles.emitting = false
         explosion_particles.emitting = false
         explosion_particles.one_shot = true
         explosion_particles.one_shot = true
 
 
     func _process(delta):
     func _process(delta):
-        
+
         if grenade_timer < GRENADE_TIME:
         if grenade_timer < GRENADE_TIME:
             grenade_timer += delta
             grenade_timer += delta
             return
             return
         else:
         else:
             if explosion_wait_timer <= 0:
             if explosion_wait_timer <= 0:
                 explosion_particles.emitting = true
                 explosion_particles.emitting = true
-                
+
                 grenade_mesh.visible = false
                 grenade_mesh.visible = false
                 rigid_shape.disabled = true
                 rigid_shape.disabled = true
-                
+
                 mode = RigidBody.MODE_STATIC
                 mode = RigidBody.MODE_STATIC
-                
+
                 var bodies = blast_area.get_overlapping_bodies()
                 var bodies = blast_area.get_overlapping_bodies()
                 for body in bodies:
                 for body in bodies:
                     if body.has_method("bullet_hit"):
                     if body.has_method("bullet_hit"):
                         body.bullet_hit(GRENADE_DAMAGE, body.global_transform.looking_at(global_transform.origin, Vector3(0,1,0)) )
                         body.bullet_hit(GRENADE_DAMAGE, body.global_transform.looking_at(global_transform.origin, Vector3(0,1,0)) )
-                
+
                 # This would be the perfect place to play a sound!
                 # This would be the perfect place to play a sound!
-                
-            
+
+
             if explosion_wait_timer < EXPLOSION_WAIT_TIME:
             if explosion_wait_timer < EXPLOSION_WAIT_TIME:
                 explosion_wait_timer += delta
                 explosion_wait_timer += delta
-                
+
                 if explosion_wait_timer >= EXPLOSION_WAIT_TIME:
                 if explosion_wait_timer >= EXPLOSION_WAIT_TIME:
                     queue_free()
                     queue_free()
 
 
@@ -93,7 +93,7 @@ Let's go over what's happening, starting with the class variables:
 * ``GRENADE_TIME``: The amount of time the grenade takes (in seconds) to explode once it's created/thrown.
 * ``GRENADE_TIME``: The amount of time the grenade takes (in seconds) to explode once it's created/thrown.
 * ``grenade_timer``: A variable for tracking how long the grenade has been created/thrown.
 * ``grenade_timer``: A variable for tracking how long the grenade has been created/thrown.
 * ``EXPLOSION_WAIT_TIME``: The amount of time needed (in seconds) to wait before we destroy the grenade scene after the explosion
 * ``EXPLOSION_WAIT_TIME``: The amount of time needed (in seconds) to wait before we destroy the grenade scene after the explosion
-* ``explosion_wait_timer``: A variable for tracking how much time has passed since the grenade exploded. 
+* ``explosion_wait_timer``: A variable for tracking how much time has passed since the grenade exploded.
 * ``rigid_shape``: The :ref:`CollisionShape <class_CollisionShape>` for the grenade's :ref:`RigidBody <class_RigidBody>`.
 * ``rigid_shape``: The :ref:`CollisionShape <class_CollisionShape>` for the grenade's :ref:`RigidBody <class_RigidBody>`.
 * ``grenade_mesh``: The :ref:`MeshInstance <class_MeshInstance>` for the grenade.
 * ``grenade_mesh``: The :ref:`MeshInstance <class_MeshInstance>` for the grenade.
 * ``blast_area``: The blast :ref:`Area <class_Area>` used to damage things when the grenade explodes.
 * ``blast_area``: The blast :ref:`Area <class_Area>` used to damage things when the grenade explodes.
@@ -154,7 +154,7 @@ the environment and needs to stick to something.
 Select ``Sticky_Grenade`` and make a new script called ``Sticky_Grenade.gd``. Add the following:
 Select ``Sticky_Grenade`` and make a new script called ``Sticky_Grenade.gd``. Add the following:
 
 
 ::
 ::
-    
+
     extends RigidBody
     extends RigidBody
 
 
     const GRENADE_DAMAGE = 40
     const GRENADE_DAMAGE = 40
@@ -180,67 +180,67 @@ Select ``Sticky_Grenade`` and make a new script called ``Sticky_Grenade.gd``. Ad
         grenade_mesh = $Sticky_Grenade
         grenade_mesh = $Sticky_Grenade
         blast_area = $Blast_Area
         blast_area = $Blast_Area
         explosion_particles = $Explosion
         explosion_particles = $Explosion
-        
+
         explosion_particles.emitting = false
         explosion_particles.emitting = false
         explosion_particles.one_shot = true
         explosion_particles.one_shot = true
-        
+
         $Sticky_Area.connect("body_entered", self, "collided_with_body")
         $Sticky_Area.connect("body_entered", self, "collided_with_body")
 
 
 
 
     func collided_with_body(body):
     func collided_with_body(body):
-        
+
         if body == self:
         if body == self:
             return
             return
-        
+
         if player_body != null:
         if player_body != null:
             if body == player_body:
             if body == player_body:
                 return
                 return
-        
+
         if attached == false:
         if attached == false:
             attached = true
             attached = true
             attach_point = Spatial.new()
             attach_point = Spatial.new()
             body.add_child(attach_point)
             body.add_child(attach_point)
             attach_point.global_transform.origin = global_transform.origin
             attach_point.global_transform.origin = global_transform.origin
-            
+
             rigid_shape.disabled = true
             rigid_shape.disabled = true
-            
+
             mode = RigidBody.MODE_STATIC
             mode = RigidBody.MODE_STATIC
 
 
 
 
     func _process(delta):
     func _process(delta):
-        
+
         if attached == true:
         if attached == true:
             if attach_point != null:
             if attach_point != null:
                 global_transform.origin = attach_point.global_transform.origin
                 global_transform.origin = attach_point.global_transform.origin
-        
+
         if grenade_timer < GRENADE_TIME:
         if grenade_timer < GRENADE_TIME:
             grenade_timer += delta
             grenade_timer += delta
             return
             return
         else:
         else:
             if explosion_wait_timer <= 0:
             if explosion_wait_timer <= 0:
                 explosion_particles.emitting = true
                 explosion_particles.emitting = true
-                
+
                 grenade_mesh.visible = false
                 grenade_mesh.visible = false
                 rigid_shape.disabled = true
                 rigid_shape.disabled = true
-                
+
                 mode = RigidBody.MODE_STATIC
                 mode = RigidBody.MODE_STATIC
-                
+
                 var bodies = blast_area.get_overlapping_bodies()
                 var bodies = blast_area.get_overlapping_bodies()
                 for body in bodies:
                 for body in bodies:
                     if body.has_method("bullet_hit"):
                     if body.has_method("bullet_hit"):
                         body.bullet_hit(GRENADE_DAMAGE, body.global_transform.looking_at(global_transform.origin, Vector3(0,1,0)) )
                         body.bullet_hit(GRENADE_DAMAGE, body.global_transform.looking_at(global_transform.origin, Vector3(0,1,0)) )
-                
+
                 # This would be the perfect place to play a sound!
                 # This would be the perfect place to play a sound!
-            
-            
+
+
             if explosion_wait_timer < EXPLOSION_WAIT_TIME:
             if explosion_wait_timer < EXPLOSION_WAIT_TIME:
                 explosion_wait_timer += delta
                 explosion_wait_timer += delta
-                
+
                 if explosion_wait_timer >= EXPLOSION_WAIT_TIME:
                 if explosion_wait_timer >= EXPLOSION_WAIT_TIME:
                     if attach_point != null:
                     if attach_point != null:
                         attach_point.queue_free()
                         attach_point.queue_free()
                     queue_free()
                     queue_free()
-                
+
 The code above is almost identical to the code for ``Grenade.gd``, so let's just go over what's changed.
 The code above is almost identical to the code for ``Grenade.gd``, so let's just go over what's changed.
 
 
 First, we have a few more class variables:
 First, we have a few more class variables:
@@ -309,7 +309,7 @@ the rotation of ``Grenade_Toss_Pos``, you can change the angle the grenades are
 Okay, now let's start making the grenades work with the player. Add the following class variables to ``Player.gd``:
 Okay, now let's start making the grenades work with the player. Add the following class variables to ``Player.gd``:
 
 
 ::
 ::
-    
+
     var grenade_amounts = {"Grenade":2, "Sticky Grenade":2}
     var grenade_amounts = {"Grenade":2, "Sticky Grenade":2}
     var current_grenade = "Grenade"
     var current_grenade = "Grenade"
     var grenade_scene = preload("res://Grenade.tscn")
     var grenade_scene = preload("res://Grenade.tscn")
@@ -321,7 +321,7 @@ Okay, now let's start making the grenades work with the player. Add the followin
 * ``grenade_scene``: The grenade scene we worked on earlier.
 * ``grenade_scene``: The grenade scene we worked on earlier.
 * ``sticky_grenade_scene``: The sticky grenade scene we worked on earlier.
 * ``sticky_grenade_scene``: The sticky grenade scene we worked on earlier.
 * ``GRENADE_THROW_FORCE``: The force at which the player will throw the grenades at.
 * ``GRENADE_THROW_FORCE``: The force at which the player will throw the grenades at.
-         
+
 Most of these variables are similar to how we have our weapons set up.
 Most of these variables are similar to how we have our weapons set up.
 
 
 .. tip:: While it's possible to make a more modular grenade system, I found it was not worth the additional complexity for just two grenades.
 .. tip:: While it's possible to make a more modular grenade system, I found it was not worth the additional complexity for just two grenades.
@@ -332,7 +332,7 @@ ______
 Now we need to add some code in ``_process_input`` Add the following to ``_process_input``:
 Now we need to add some code in ``_process_input`` Add the following to ``_process_input``:
 
 
 ::
 ::
-    
+
     # ----------------------------------
     # ----------------------------------
     # Changing and throwing grenades
     # Changing and throwing grenades
 
 
@@ -345,7 +345,7 @@ Now we need to add some code in ``_process_input`` Add the following to ``_proce
     if Input.is_action_just_pressed("fire_grenade"):
     if Input.is_action_just_pressed("fire_grenade"):
         if grenade_amounts[current_grenade] > 0:
         if grenade_amounts[current_grenade] > 0:
             grenade_amounts[current_grenade] -= 1
             grenade_amounts[current_grenade] -= 1
-            
+
             var grenade_clone
             var grenade_clone
             if current_grenade == "Grenade":
             if current_grenade == "Grenade":
                 grenade_clone = grenade_scene.instance()
                 grenade_clone = grenade_scene.instance()
@@ -353,12 +353,12 @@ Now we need to add some code in ``_process_input`` Add the following to ``_proce
                 grenade_clone = sticky_grenade_scene.instance()
                 grenade_clone = sticky_grenade_scene.instance()
                 # Sticky grenades will stick to the player if we do not pass ourselves
                 # Sticky grenades will stick to the player if we do not pass ourselves
                 grenade_clone.player_body = self
                 grenade_clone.player_body = self
-            
+
             get_tree().root.add_child(grenade_clone)
             get_tree().root.add_child(grenade_clone)
             grenade_clone.global_transform = $Rotation_Helper/Grenade_Toss_Pos.global_transform
             grenade_clone.global_transform = $Rotation_Helper/Grenade_Toss_Pos.global_transform
             grenade_clone.apply_impulse(Vector3(0,0,0), grenade_clone.global_transform.basis.z * GRENADE_THROW_FORCE)
             grenade_clone.apply_impulse(Vector3(0,0,0), grenade_clone.global_transform.basis.z * GRENADE_THROW_FORCE)
     # ----------------------------------
     # ----------------------------------
-         
+
 Let's go over what's happening here.
 Let's go over what's happening here.
 
 
 First, we check to see if the ``change_grenade`` action has just been pressed. If it has, we then check to see which grenade the player is
 First, we check to see if the ``change_grenade`` action has just been pressed. If it has, we then check to see which grenade the player is
@@ -383,7 +383,7 @@ We still need a way to show the player how many grenades are left, and we should
 First, let's change some of the code in ``Player.gd`` to show how many grenades are left. Change ``process_UI`` to the following:
 First, let's change some of the code in ``Player.gd`` to show how many grenades are left. Change ``process_UI`` to the following:
 
 
 ::
 ::
-    
+
     func process_UI(delta):
     func process_UI(delta):
         if current_weapon_name == "UNARMED" or current_weapon_name == "KNIFE":
         if current_weapon_name == "UNARMED" or current_weapon_name == "KNIFE":
             # First line: Health, second line: Grenades
             # First line: Health, second line: Grenades
@@ -401,7 +401,7 @@ Now we'll show how many grenades the player has left in the UI.
 While we're still in ``Player.gd``, let's add a function to add grenades to the player. Add the following function to ``Player.gd``:
 While we're still in ``Player.gd``, let's add a function to add grenades to the player. Add the following function to ``Player.gd``:
 
 
 ::
 ::
-    
+
     func add_grenade(additional_grenade):
     func add_grenade(additional_grenade):
         grenade_amounts[current_grenade] += additional_grenade
         grenade_amounts[current_grenade] += additional_grenade
         grenade_amounts[current_grenade] = clamp(grenade_amounts[current_grenade], 0, 4)
         grenade_amounts[current_grenade] = clamp(grenade_amounts[current_grenade], 0, 4)
@@ -410,7 +410,7 @@ Now we can add a grenade using ``add_grenade``, and it will automatically be cla
 
 
 .. tip:: You can change the ``4`` to a constant if you want. You'd need to make a new global constant, something like ``MAX_GRENADES``, and
 .. tip:: You can change the ``4`` to a constant if you want. You'd need to make a new global constant, something like ``MAX_GRENADES``, and
          then change the clamp from ``clamp(grenade_amounts[current_grenade], 0, 4)`` to ``clamp(grenade_amounts[current_grenade], 0, MAX_GRENADES)``
          then change the clamp from ``clamp(grenade_amounts[current_grenade], 0, 4)`` to ``clamp(grenade_amounts[current_grenade], 0, MAX_GRENADES)``
-         
+
          If you do not want to limit how many grenades the player can carry, remove the line that clamps the grenades altogether!
          If you do not want to limit how many grenades the player can carry, remove the line that clamps the grenades altogether!
 
 
 Now we have a function to add grenades, let's open up ``AmmoPickup.gd`` and use it!
 Now we have a function to add grenades, let's open up ``AmmoPickup.gd`` and use it!
@@ -418,13 +418,13 @@ Now we have a function to add grenades, let's open up ``AmmoPickup.gd`` and use
 Open up ``AmmoPickup.gd`` and go to the ``trigger_body_entered`` function. Change it to the following:
 Open up ``AmmoPickup.gd`` and go to the ``trigger_body_entered`` function. Change it to the following:
 
 
 ::
 ::
-    
+
     func trigger_body_entered(body):
     func trigger_body_entered(body):
         if body.has_method("add_ammo"):
         if body.has_method("add_ammo"):
             body.add_ammo(AMMO_AMOUNTS[kit_size])
             body.add_ammo(AMMO_AMOUNTS[kit_size])
             respawn_timer = RESPAWN_TIME
             respawn_timer = RESPAWN_TIME
             kit_size_change_values(kit_size, false)
             kit_size_change_values(kit_size, false)
-        
+
         if body.has_method("add_grenade"):
         if body.has_method("add_grenade"):
             body.add_grenade(GRENADE_AMOUNTS[kit_size])
             body.add_grenade(GRENADE_AMOUNTS[kit_size])
             respawn_timer = RESPAWN_TIME
             respawn_timer = RESPAWN_TIME
@@ -436,9 +436,9 @@ You may have noticed we are using a new constant we have not defined yet, ``GREN
 to ``AmmoPickup.gd`` with the other class variables:
 to ``AmmoPickup.gd`` with the other class variables:
 
 
 ::
 ::
-    
+
     const GRENADE_AMOUNTS = [2, 0]
     const GRENADE_AMOUNTS = [2, 0]
-    
+
 * ``GRENADE_AMOUNTS``: The amount of grenades each pick up contains.
 * ``GRENADE_AMOUNTS``: The amount of grenades each pick up contains.
 
 
 Notice how the second element in ``GRENADE_AMOUNTS`` is ``0``. This is so the small ammo pick up does not give the player
 Notice how the second element in ``GRENADE_AMOUNTS`` is ``0``. This is so the small ammo pick up does not give the player
@@ -457,7 +457,7 @@ Next let's give the player the ability to pick up and throw :ref:`RigidBody <cla
 Open up ``Player.gd`` and add the following class variables:
 Open up ``Player.gd`` and add the following class variables:
 
 
 ::
 ::
-    
+
     var grabbed_object = null
     var grabbed_object = null
     const OBJECT_THROW_FORCE = 120
     const OBJECT_THROW_FORCE = 120
     const OBJECT_GRAB_DISTANCE = 7
     const OBJECT_GRAB_DISTANCE = 7
@@ -471,35 +471,35 @@ Open up ``Player.gd`` and add the following class variables:
 With that done, all we need to do is add some code to ``process_input``:
 With that done, all we need to do is add some code to ``process_input``:
 
 
 ::
 ::
-    
+
     # ----------------------------------
     # ----------------------------------
     # Grabbing and throwing objects
     # Grabbing and throwing objects
 
 
     if Input.is_action_just_pressed("fire") and current_weapon_name == "UNARMED":
     if Input.is_action_just_pressed("fire") and current_weapon_name == "UNARMED":
         if grabbed_object == null:
         if grabbed_object == null:
             var state = get_world().direct_space_state
             var state = get_world().direct_space_state
-            
+
             var center_position = get_viewport().size/2
             var center_position = get_viewport().size/2
             var ray_from = camera.project_ray_origin(center_position)
             var ray_from = camera.project_ray_origin(center_position)
             var ray_to = ray_from + camera.project_ray_normal(center_position) * OBJECT_GRAB_RAY_DISTANCE
             var ray_to = ray_from + camera.project_ray_normal(center_position) * OBJECT_GRAB_RAY_DISTANCE
-            
+
             var ray_result = state.intersect_ray(ray_from, ray_to, [self, $Rotation_Helper/Gun_Fire_Points/Knife_Point/Area])
             var ray_result = state.intersect_ray(ray_from, ray_to, [self, $Rotation_Helper/Gun_Fire_Points/Knife_Point/Area])
             if ray_result != null:
             if ray_result != null:
                 if ray_result["collider"] is RigidBody:
                 if ray_result["collider"] is RigidBody:
                     grabbed_object = ray_result["collider"]
                     grabbed_object = ray_result["collider"]
                     grabbed_object.mode = RigidBody.MODE_STATIC
                     grabbed_object.mode = RigidBody.MODE_STATIC
-                    
+
                     grabbed_object.collision_layer = 0
                     grabbed_object.collision_layer = 0
                     grabbed_object.collision_mask = 0
                     grabbed_object.collision_mask = 0
-        
+
         else:
         else:
             grabbed_object.mode = RigidBody.MODE_RIGID
             grabbed_object.mode = RigidBody.MODE_RIGID
-            
+
             grabbed_object.apply_impulse(Vector3(0,0,0), -camera.global_transform.basis.z.normalized() * OBJECT_THROW_FORCE)
             grabbed_object.apply_impulse(Vector3(0,0,0), -camera.global_transform.basis.z.normalized() * OBJECT_THROW_FORCE)
-            
+
             grabbed_object.collision_layer = 1
             grabbed_object.collision_layer = 1
             grabbed_object.collision_mask = 1
             grabbed_object.collision_mask = 1
-            
+
             grabbed_object = null
             grabbed_object = null
 
 
     if grabbed_object != null:
     if grabbed_object != null:
@@ -545,10 +545,10 @@ We first set the :ref:`RigidBody <class_RigidBody>` we are holding mode to ``MOD
 
 
 .. note:: This is making a rather large assumption that all the rigid bodies will be using ``MODE_RIGID``. While that is the case for this tutorial series,
 .. note:: This is making a rather large assumption that all the rigid bodies will be using ``MODE_RIGID``. While that is the case for this tutorial series,
           that may not be the case in other projects.
           that may not be the case in other projects.
-          
+
           If you have :ref:`RigidBody <class_RigidBody>`'s with different modes, you may need to store the mode of the :ref:`RigidBody <class_RigidBody>` you
           If you have :ref:`RigidBody <class_RigidBody>`'s with different modes, you may need to store the mode of the :ref:`RigidBody <class_RigidBody>` you
           have picked up into a class variable so you can change it back to the mode it was in before you picked it up.
           have picked up into a class variable so you can change it back to the mode it was in before you picked it up.
-  
+
 Then we apply an impulse to send it flying forward. We send it flying in the direction the camera is facing, using the force we set in the ``OBJECT_THROW_FORCE`` variable.
 Then we apply an impulse to send it flying forward. We send it flying in the direction the camera is facing, using the force we set in the ``OBJECT_THROW_FORCE`` variable.
 
 
 We then set the grabbed :ref:`RigidBody <class_RigidBody>`'s collision layer and mask to ``1``, so it can collide with anything on layer ``1`` again.
 We then set the grabbed :ref:`RigidBody <class_RigidBody>`'s collision layer and mask to ``1``, so it can collide with anything on layer ``1`` again.
@@ -573,7 +573,7 @@ Before we test this, we need to change something in ``_physics_process``. While
 want the player to be able to change weapons or reload, so change ``_physics_process`` to the following:
 want the player to be able to change weapons or reload, so change ``_physics_process`` to the following:
 
 
 ::
 ::
-    
+
     func _physics_process(delta):
     func _physics_process(delta):
         process_input(delta)
         process_input(delta)
         process_view_input(delta)
         process_view_input(delta)
@@ -587,7 +587,7 @@ want the player to be able to change weapons or reload, so change ``_physics_pro
         process_UI(delta)
         process_UI(delta)
 
 
 Now the player cannot change weapons or reload while holding an object.
 Now the player cannot change weapons or reload while holding an object.
-    
+
 Now you can grab and throw RigidBody nodes while you're in the ``UNARMED`` state! Go give it a try!
 Now you can grab and throw RigidBody nodes while you're in the ``UNARMED`` state! Go give it a try!
 
 
 Adding a turret
 Adding a turret
@@ -615,7 +615,7 @@ Now that we've looked at how the scene is set up, lets start writing the code fo
 Add the following to ``Turret.gd``:
 Add the following to ``Turret.gd``:
 
 
 ::
 ::
-    
+
     extends Spatial
     extends Spatial
 
 
     export (bool) var use_raycast = false
     export (bool) var use_raycast = false
@@ -656,46 +656,46 @@ Add the following to ``Turret.gd``:
     var bullet_scene = preload("Bullet_Scene.tscn")
     var bullet_scene = preload("Bullet_Scene.tscn")
 
 
     func _ready():
     func _ready():
-        
+
         $Vision_Area.connect("body_entered", self, "body_entered_vision")
         $Vision_Area.connect("body_entered", self, "body_entered_vision")
         $Vision_Area.connect("body_exited", self, "body_exited_vision")
         $Vision_Area.connect("body_exited", self, "body_exited_vision")
-        
+
         node_turret_head = $Head
         node_turret_head = $Head
         node_raycast = $Head/Ray_Cast
         node_raycast = $Head/Ray_Cast
         node_flash_one = $Head/Flash
         node_flash_one = $Head/Flash
         node_flash_two = $Head/Flash_2
         node_flash_two = $Head/Flash_2
-        
+
         node_raycast.add_exception(self)
         node_raycast.add_exception(self)
         node_raycast.add_exception($Base/Static_Body)
         node_raycast.add_exception($Base/Static_Body)
         node_raycast.add_exception($Head/Static_Body)
         node_raycast.add_exception($Head/Static_Body)
         node_raycast.add_exception($Vision_Area)
         node_raycast.add_exception($Vision_Area)
-        
+
         node_flash_one.visible = false
         node_flash_one.visible = false
         node_flash_two.visible = false
         node_flash_two.visible = false
-        
+
         smoke_particles = $Smoke
         smoke_particles = $Smoke
         smoke_particles.emitting = false
         smoke_particles.emitting = false
-        
+
         turret_health = MAX_TURRET_HEALTH
         turret_health = MAX_TURRET_HEALTH
 
 
 
 
     func _physics_process(delta):
     func _physics_process(delta):
-        
+
         if is_active == true:
         if is_active == true:
-            
+
             if flash_timer > 0:
             if flash_timer > 0:
                 flash_timer -= delta
                 flash_timer -= delta
-                
+
                 if flash_timer <= 0:
                 if flash_timer <= 0:
                     node_flash_one.visible = false
                     node_flash_one.visible = false
                     node_flash_two.visible = false
                     node_flash_two.visible = false
-            
+
             if current_target != null:
             if current_target != null:
-                
+
                 node_turret_head.look_at(current_target.global_transform.origin + Vector3(0, PLAYER_HEIGHT, 0), Vector3(0, 1, 0))
                 node_turret_head.look_at(current_target.global_transform.origin + Vector3(0, PLAYER_HEIGHT, 0), Vector3(0, 1, 0))
-                
+
                 if turret_health > 0:
                 if turret_health > 0:
-                    
+
                     if ammo_in_turret > 0:
                     if ammo_in_turret > 0:
                         if fire_timer > 0:
                         if fire_timer > 0:
                             fire_timer -= delta
                             fire_timer -= delta
@@ -706,7 +706,7 @@ Add the following to ``Turret.gd``:
                             ammo_reload_timer -= delta
                             ammo_reload_timer -= delta
                         else:
                         else:
                             ammo_in_turret = AMMO_IN_FULL_TURRET
                             ammo_in_turret = AMMO_IN_FULL_TURRET
-        
+
         if turret_health <= 0:
         if turret_health <= 0:
             if destroyed_timer > 0:
             if destroyed_timer > 0:
                 destroyed_timer -= delta
                 destroyed_timer -= delta
@@ -716,40 +716,40 @@ Add the following to ``Turret.gd``:
 
 
 
 
     func fire_bullet():
     func fire_bullet():
-    
+
     if use_raycast == true:
     if use_raycast == true:
         node_raycast.look_at(current_target.global_transform.origin + Vector3(0, PLAYER_HEIGHT, 0), Vector3(0,1,0))
         node_raycast.look_at(current_target.global_transform.origin + Vector3(0, PLAYER_HEIGHT, 0), Vector3(0,1,0))
-        
+
         node_raycast.force_raycast_update()
         node_raycast.force_raycast_update()
-        
+
         if node_raycast.is_colliding():
         if node_raycast.is_colliding():
             var body = node_raycast.get_collider()
             var body = node_raycast.get_collider()
             if body.has_method("bullet_hit"):
             if body.has_method("bullet_hit"):
                 body.bullet_hit(TURRET_DAMAGE_RAYCAST, node_raycast.get_collision_point())
                 body.bullet_hit(TURRET_DAMAGE_RAYCAST, node_raycast.get_collision_point())
-        
+
         ammo_in_turret -= 1
         ammo_in_turret -= 1
-        
+
     else:
     else:
         var clone = bullet_scene.instance()
         var clone = bullet_scene.instance()
         var scene_root = get_tree().root.get_children()[0]
         var scene_root = get_tree().root.get_children()[0]
         scene_root.add_child(clone)
         scene_root.add_child(clone)
-        
+
         clone.global_transform = $Head/Barrel_End.global_transform
         clone.global_transform = $Head/Barrel_End.global_transform
         clone.scale = Vector3(8, 8, 8)
         clone.scale = Vector3(8, 8, 8)
         clone.BULLET_DAMAGE = TURRET_DAMAGE_BULLET
         clone.BULLET_DAMAGE = TURRET_DAMAGE_BULLET
         clone.BULLET_SPEED = 60
         clone.BULLET_SPEED = 60
-                
+
         ammo_in_turret -= 1
         ammo_in_turret -= 1
-        
+
     node_flash_one.visible = true
     node_flash_one.visible = true
     node_flash_two.visible = true
     node_flash_two.visible = true
-    
+
     flash_timer = FLASH_TIME
     flash_timer = FLASH_TIME
     fire_timer = FIRE_TIME
     fire_timer = FIRE_TIME
-    
+
     if ammo_in_turret <= 0:
     if ammo_in_turret <= 0:
         ammo_reload_timer = AMMO_RELOAD_TIME
         ammo_reload_timer = AMMO_RELOAD_TIME
-        
+
 
 
     func body_entered_vision(body):
     func body_entered_vision(body):
         if current_target == null:
         if current_target == null:
@@ -763,7 +763,7 @@ Add the following to ``Turret.gd``:
             if body == current_target:
             if body == current_target:
                 current_target = null
                 current_target = null
                 is_active = false
                 is_active = false
-                
+
                 flash_timer = 0
                 flash_timer = 0
                 fire_timer = 0
                 fire_timer = 0
                 node_flash_one.visible = false
                 node_flash_one.visible = false
@@ -772,7 +772,7 @@ Add the following to ``Turret.gd``:
 
 
     func bullet_hit(damage, bullet_hit_pos):
     func bullet_hit(damage, bullet_hit_pos):
         turret_health -= damage
         turret_health -= damage
-        
+
         if turret_health <= 0:
         if turret_health <= 0:
             smoke_particles.emitting = true
             smoke_particles.emitting = true
             destroyed_timer = DESTROYED_TIME
             destroyed_timer = DESTROYED_TIME
@@ -916,7 +916,7 @@ select one of the :ref:`StaticBody <class_StaticBody>` nodes from either ``Base`
 Add the following code to ``TurretBodies.gd``:
 Add the following code to ``TurretBodies.gd``:
 
 
 ::
 ::
-    
+
     extends StaticBody
     extends StaticBody
 
 
     export (NodePath) var path_to_turret_root
     export (NodePath) var path_to_turret_root
@@ -927,7 +927,7 @@ Add the following code to ``TurretBodies.gd``:
     func bullet_hit(damage, bullet_hit_pos):
     func bullet_hit(damage, bullet_hit_pos):
         if path_to_turret_root != null:
         if path_to_turret_root != null:
             get_node(path_to_turret_root).bullet_hit(damage, bullet_hit_pos)
             get_node(path_to_turret_root).bullet_hit(damage, bullet_hit_pos)
-            
+
 All this code does is call ``bullet_hit`` on whatever node ``path_to_turret_root`` leads to. Go back to the editor and assign the :ref:`NodePath <class_NodePath>`
 All this code does is call ``bullet_hit`` on whatever node ``path_to_turret_root`` leads to. Go back to the editor and assign the :ref:`NodePath <class_NodePath>`
 to the ``Turret`` node.
 to the ``Turret`` node.
 
 
@@ -941,7 +941,7 @@ The last thing we need to do is add a way for the player to be hurt. Since all o
 Open ``Player.gd`` and add the following:
 Open ``Player.gd`` and add the following:
 
 
 ::
 ::
-    
+
     func bullet_hit(damage, bullet_hit_pos):
     func bullet_hit(damage, bullet_hit_pos):
         health -= damage
         health -= damage
 
 

+ 51 - 51
tutorials/3d/fps_tutorial/part_four.rst

@@ -41,14 +41,14 @@ Feel free to use whatever button layout you want. Make sure that the device sele
 
 
 Once you are happy with the input, close the project settings and save.
 Once you are happy with the input, close the project settings and save.
 
 
-______ 
+______
 
 
 Now let's open up ``Player.gd`` and add joypad input.
 Now let's open up ``Player.gd`` and add joypad input.
 
 
 First, we need to define a few new class variables. Add the following class variables to ``Player.gd``:
 First, we need to define a few new class variables. Add the following class variables to ``Player.gd``:
 
 
 ::
 ::
-    
+
     # You may need to adjust depending on the sensitivity of your joypad
     # You may need to adjust depending on the sensitivity of your joypad
     var JOYPAD_SENSITIVITY = 2
     var JOYPAD_SENSITIVITY = 2
     const JOYPAD_DEADZONE = 0.15
     const JOYPAD_DEADZONE = 0.15
@@ -60,23 +60,23 @@ Let's go over what each of these do:
 
 
 .. note::  Many joypads jitter around a certain point. To counter this, we ignore any movement in a
 .. note::  Many joypads jitter around a certain point. To counter this, we ignore any movement in a
            with a radius of JOYPAD_DEADZONE. If we did not ignore said movement, the camera would jitter.
            with a radius of JOYPAD_DEADZONE. If we did not ignore said movement, the camera would jitter.
-           
+
            Also, we are defining ``JOYPAD_SENSITIVITY`` as a variable instead of a constant because we'll later be changing it.
            Also, we are defining ``JOYPAD_SENSITIVITY`` as a variable instead of a constant because we'll later be changing it.
 
 
-Now we are ready to start handling joypad input!           
+Now we are ready to start handling joypad input!
 
 
 ______
 ______
-           
+
 In ``process_input`` add the following code, just before ``input_movement_vector = input_movement_vector.normalized()``:
 In ``process_input`` add the following code, just before ``input_movement_vector = input_movement_vector.normalized()``:
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript Xbox Controller
  .. code-tab:: gdscript Xbox Controller
-    
+
     # Add joypad input, if there is a joypad
     # Add joypad input, if there is a joypad
     if Input.get_connected_joypads().size() > 0:
     if Input.get_connected_joypads().size() > 0:
-        
+
         var joypad_vec = Vector2(0, 0)
         var joypad_vec = Vector2(0, 0)
-        
+
         if OS.get_name() == "Windows":
         if OS.get_name() == "Windows":
             joypad_vec = Vector2(Input.get_joy_axis(0, 0), -Input.get_joy_axis(0, 1))
             joypad_vec = Vector2(Input.get_joy_axis(0, 0), -Input.get_joy_axis(0, 1))
         elif OS.get_name() == "X11":
         elif OS.get_name() == "X11":
@@ -95,9 +95,9 @@ In ``process_input`` add the following code, just before ``input_movement_vector
 
 
     # Add joypad input, if there is a joypad
     # Add joypad input, if there is a joypad
     if Input.get_connected_joypads().size() > 0:
     if Input.get_connected_joypads().size() > 0:
-        
+
         var joypad_vec = Vector2(0, 0)
         var joypad_vec = Vector2(0, 0)
-        
+
         if OS.get_name() == "Windows" or OS.get_name() == "X11":
         if OS.get_name() == "Windows" or OS.get_name() == "X11":
             joypad_vec = Vector2(Input.get_joy_axis(0, 0), -Input.get_joy_axis(0, 1))
             joypad_vec = Vector2(Input.get_joy_axis(0, 0), -Input.get_joy_axis(0, 1))
         elif OS.get_name() == "OSX":
         elif OS.get_name() == "OSX":
@@ -127,7 +127,7 @@ If it is, we set ``joypad_vec`` to an empty Vector2. If it is not, we use a scal
 
 
 .. note:: You can find a great article explaining all about how to handle joypad/controller dead zones here:
 .. note:: You can find a great article explaining all about how to handle joypad/controller dead zones here:
           http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html
           http://www.third-helix.com/2013/04/12/doing-thumbstick-dead-zones-right.html
-            
+
           We're using a translated version of the scaled radial dead zone code provided in that article.
           We're using a translated version of the scaled radial dead zone code provided in that article.
           The article is a great read, and I highly suggest giving it a look!
           The article is a great read, and I highly suggest giving it a look!
 
 
@@ -135,16 +135,16 @@ Finally, we add ``joypad_vec`` to ``input_movement_vector``.
 
 
 .. tip:: Remember how we normalize ``input_movement_vector``? This is why! If we did not normalize ``input_movement_vector``, the player could
 .. tip:: Remember how we normalize ``input_movement_vector``? This is why! If we did not normalize ``input_movement_vector``, the player could
          move faster if the player pushes in the same direction with both the keyboard and the joypad!
          move faster if the player pushes in the same direction with both the keyboard and the joypad!
-         
+
 ______
 ______
 
 
 Make a new function called ``process_view_input`` and add the following:
 Make a new function called ``process_view_input`` and add the following:
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript Xbox Controller
  .. code-tab:: gdscript Xbox Controller
-    
+
     func process_view_input(delta):
     func process_view_input(delta):
-        
+
         if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
         if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
             return
             return
 
 
@@ -179,9 +179,9 @@ Make a new function called ``process_view_input`` and add the following:
         # ----------------------------------
         # ----------------------------------
 
 
  .. code-tab:: gdscript Playstation Controller
  .. code-tab:: gdscript Playstation Controller
-     
+
      func process_view_input(delta):
      func process_view_input(delta):
-        
+
         if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
         if Input.get_mouse_mode() != Input.MOUSE_MODE_CAPTURED:
             return
             return
 
 
@@ -242,10 +242,10 @@ The last thing we need to do is add ``process_view_input`` to ``_physics_process
 Once ``process_view_input`` is added to ``_physics_process``, you should be able to play using a joypad!
 Once ``process_view_input`` is added to ``_physics_process``, you should be able to play using a joypad!
 
 
 .. note:: I decided not to use the joypad triggers for firing because we'd then have to do some more axis managing, and because I prefer to use a shoulder buttons to fire.
 .. note:: I decided not to use the joypad triggers for firing because we'd then have to do some more axis managing, and because I prefer to use a shoulder buttons to fire.
-          
+
           If you want to use the triggers for firing, you will need to change how firing works in ``process_input``. You need to get the axis values for the triggers,
           If you want to use the triggers for firing, you will need to change how firing works in ``process_input``. You need to get the axis values for the triggers,
           and check if it's over a certain value, say ``0.8`` for example. If it is, you add the same code as when the ``fire`` action was pressed.
           and check if it's over a certain value, say ``0.8`` for example. If it is, you add the same code as when the ``fire`` action was pressed.
-         
+
 Adding mouse scroll wheel input
 Adding mouse scroll wheel input
 -------------------------------
 -------------------------------
 
 
@@ -254,7 +254,7 @@ Let's add one more input related feature before we start working on the pick ups
 Open up ``Player.gd`` and add the following class variables:
 Open up ``Player.gd`` and add the following class variables:
 
 
 ::
 ::
-    
+
     var mouse_scroll_value = 0
     var mouse_scroll_value = 0
     const MOUSE_SENSITIVITY_SCROLL_WHEEL = 0.08
     const MOUSE_SENSITIVITY_SCROLL_WHEEL = 0.08
 
 
@@ -268,16 +268,16 @@ ______
 Now let's add the following to ``_input``:
 Now let's add the following to ``_input``:
 
 
 ::
 ::
-    
+
     if event is InputEventMouseButton and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
     if event is InputEventMouseButton and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
         if event.button_index == BUTTON_WHEEL_UP or event.button_index == BUTTON_WHEEL_DOWN:
         if event.button_index == BUTTON_WHEEL_UP or event.button_index == BUTTON_WHEEL_DOWN:
             if event.button_index == BUTTON_WHEEL_UP:
             if event.button_index == BUTTON_WHEEL_UP:
                 mouse_scroll_value += MOUSE_SENSITIVITY_SCROLL_WHEEL
                 mouse_scroll_value += MOUSE_SENSITIVITY_SCROLL_WHEEL
             elif event.button_index == BUTTON_WHEEL_DOWN:
             elif event.button_index == BUTTON_WHEEL_DOWN:
                 mouse_scroll_value -= MOUSE_SENSITIVITY_SCROLL_WHEEL
                 mouse_scroll_value -= MOUSE_SENSITIVITY_SCROLL_WHEEL
-            
+
             mouse_scroll_value = clamp(mouse_scroll_value, 0, WEAPON_NUMBER_TO_NAME.size()-1)
             mouse_scroll_value = clamp(mouse_scroll_value, 0, WEAPON_NUMBER_TO_NAME.size()-1)
-            
+
             if changing_weapon == false:
             if changing_weapon == false:
                 if reloading_weapon == false:
                 if reloading_weapon == false:
                     var round_mouse_scroll_value = int(round(mouse_scroll_value))
                     var round_mouse_scroll_value = int(round(mouse_scroll_value))
@@ -286,7 +286,7 @@ Now let's add the following to ``_input``:
                         changing_weapon = true
                         changing_weapon = true
                         mouse_scroll_value = round_mouse_scroll_value
                         mouse_scroll_value = round_mouse_scroll_value
 
 
-                        
+
 Let's go over what's happening here:
 Let's go over what's happening here:
 
 
 First we check if the event is a ``InputEventMouseButton`` event and that the mouse mode is ``MOUSE_MODE_CAPTURED``.
 First we check if the event is a ``InputEventMouseButton`` event and that the mouse mode is ``MOUSE_MODE_CAPTURED``.
@@ -315,9 +315,9 @@ ______
 One more thing we need to change is in ``process_input``. In the code for changing weapons, add the following right after the line ``changing_weapon = true``:
 One more thing we need to change is in ``process_input``. In the code for changing weapons, add the following right after the line ``changing_weapon = true``:
 
 
 ::
 ::
-    
+
     mouse_scroll_value = weapon_change_number
     mouse_scroll_value = weapon_change_number
-    
+
 Now the scroll value will be changed with the keyboard input. If we did not change this, the scroll value will be out of sync. If the scroll wheel is out of
 Now the scroll value will be changed with the keyboard input. If we did not change this, the scroll value will be out of sync. If the scroll wheel is out of
 sync, scrolling forwards or backwards would not transition to the next/last weapon, but rather the next/last weapon the scroll wheel changed to.
 sync, scrolling forwards or backwards would not transition to the next/last weapon, but rather the next/last weapon the scroll wheel changed to.
 
 
@@ -346,7 +346,7 @@ The last thing to note is how we have a :ref:`AnimationPlayer <class_AnimationPl
 Select ``Health_Pickup`` and add a new script called ``Health_Pickup.gd``. Add the following:
 Select ``Health_Pickup`` and add a new script called ``Health_Pickup.gd``. Add the following:
 
 
 ::
 ::
-    
+
     extends Spatial
     extends Spatial
 
 
     export (int, "full size", "small") var kit_size = 0 setget kit_size_change
     export (int, "full size", "small") var kit_size = 0 setget kit_size_change
@@ -360,11 +360,11 @@ Select ``Health_Pickup`` and add a new script called ``Health_Pickup.gd``. Add t
     var is_ready = false
     var is_ready = false
 
 
     func _ready():
     func _ready():
-        
+
         $Holder/Health_Pickup_Trigger.connect("body_entered", self, "trigger_body_entered")
         $Holder/Health_Pickup_Trigger.connect("body_entered", self, "trigger_body_entered")
-        
+
         is_ready = true
         is_ready = true
-        
+
         kit_size_change_values(0, false)
         kit_size_change_values(0, false)
         kit_size_change_values(1, false)
         kit_size_change_values(1, false)
         kit_size_change_values(kit_size, true)
         kit_size_change_values(kit_size, true)
@@ -373,7 +373,7 @@ Select ``Health_Pickup`` and add a new script called ``Health_Pickup.gd``. Add t
     func _physics_process(delta):
     func _physics_process(delta):
         if respawn_timer > 0:
         if respawn_timer > 0:
             respawn_timer -= delta
             respawn_timer -= delta
-            
+
             if respawn_timer <= 0:
             if respawn_timer <= 0:
                 kit_size_change_values(kit_size, true)
                 kit_size_change_values(kit_size, true)
 
 
@@ -457,7 +457,7 @@ We get the collision shape for the node corresponding to ``size`` and disable it
 .. note:: Why are we using ``!enable`` instead of ``enable``? This is so when we say we want to enable the node, we can pass in ``true``, but since
 .. note:: Why are we using ``!enable`` instead of ``enable``? This is so when we say we want to enable the node, we can pass in ``true``, but since
           :ref:`CollisionShape <class_CollisionShape>` uses disabled instead of enabled, we need to flip it. By flipping it, we can enable the collision shape
           :ref:`CollisionShape <class_CollisionShape>` uses disabled instead of enabled, we need to flip it. By flipping it, we can enable the collision shape
           and make the mesh visible when ``true`` is passed in.
           and make the mesh visible when ``true`` is passed in.
-  
+
 We then get the correct :ref:`Spatial <class_Spatial>` node holding the mesh and set its visibility to ``enable``.
 We then get the correct :ref:`Spatial <class_Spatial>` node holding the mesh and set its visibility to ``enable``.
 
 
 This function may be a little confusing, try to think of it like this: We're enabling/disabling the proper nodes for ``size`` using ``enabled``. This is so we cannot pick up
 This function may be a little confusing, try to think of it like this: We're enabling/disabling the proper nodes for ``size`` using ``enabled``. This is so we cannot pick up
@@ -480,15 +480,15 @@ The last thing we need to do before the player can use this health pick up is ad
 Open up ``Player.gd`` and add the following class variable:
 Open up ``Player.gd`` and add the following class variable:
 
 
 ::
 ::
-    
+
     const MAX_HEALTH = 150
     const MAX_HEALTH = 150
-    
+
 * ``MAX_HEALTH``: The maximum amount of health a player can have.
 * ``MAX_HEALTH``: The maximum amount of health a player can have.
 
 
 Now we need to add the ``add_health`` function to the player. Add the following to ``Player.gd``:
 Now we need to add the ``add_health`` function to the player. Add the following to ``Player.gd``:
 
 
 ::
 ::
-    
+
     func add_health(additional_health):
     func add_health(additional_health):
         health += additional_health
         health += additional_health
         health = clamp(health, 0, MAX_HEALTH)
         health = clamp(health, 0, MAX_HEALTH)
@@ -515,35 +515,35 @@ for the difference in mesh sizes.
 Select ``Ammo_Pickup`` and add a new script called ``Ammo_Pickup.gd``. Add the following:
 Select ``Ammo_Pickup`` and add a new script called ``Ammo_Pickup.gd``. Add the following:
 
 
 ::
 ::
-    
+
     extends Spatial
     extends Spatial
 
 
     export (int, "full size", "small") var kit_size = 0 setget kit_size_change
     export (int, "full size", "small") var kit_size = 0 setget kit_size_change
 
 
     # 0 = full size pickup, 1 = small pickup
     # 0 = full size pickup, 1 = small pickup
     const AMMO_AMOUNTS = [4, 1]
     const AMMO_AMOUNTS = [4, 1]
-    
+
     const RESPAWN_TIME = 20
     const RESPAWN_TIME = 20
     var respawn_timer = 0
     var respawn_timer = 0
 
 
     var is_ready = false
     var is_ready = false
 
 
     func _ready():
     func _ready():
-        
+
         $Holder/Ammo_Pickup_Trigger.connect("body_entered", self, "trigger_body_entered")
         $Holder/Ammo_Pickup_Trigger.connect("body_entered", self, "trigger_body_entered")
-        
+
         is_ready = true
         is_ready = true
-        
+
         kit_size_change_values(0, false)
         kit_size_change_values(0, false)
         kit_size_change_values(1, false)
         kit_size_change_values(1, false)
-        
+
         kit_size_change_values(kit_size, true)
         kit_size_change_values(kit_size, true)
 
 
 
 
     func _physics_process(delta):
     func _physics_process(delta):
         if respawn_timer > 0:
         if respawn_timer > 0:
             respawn_timer -= delta
             respawn_timer -= delta
-            
+
             if respawn_timer <= 0:
             if respawn_timer <= 0:
                 kit_size_change_values(kit_size, true)
                 kit_size_change_values(kit_size, true)
 
 
@@ -552,7 +552,7 @@ Select ``Ammo_Pickup`` and add a new script called ``Ammo_Pickup.gd``. Add the f
         if is_ready:
         if is_ready:
             kit_size_change_values(kit_size, false)
             kit_size_change_values(kit_size, false)
             kit_size = value
             kit_size = value
-            
+
             kit_size_change_values(kit_size, true)
             kit_size_change_values(kit_size, true)
         else:
         else:
             kit_size = value
             kit_size = value
@@ -588,7 +588,7 @@ _______
 All we need to do for making the ammo pick ups work is to add a new function to the player. Open ``Player.gd`` and add the following function:
 All we need to do for making the ammo pick ups work is to add a new function to the player. Open ``Player.gd`` and add the following function:
 
 
 ::
 ::
-    
+
     func add_ammo(additional_ammo):
     func add_ammo(additional_ammo):
         if (current_weapon_name != "UNARMED"):
         if (current_weapon_name != "UNARMED"):
             if (weapons[current_weapon_name].CAN_REFILL == true):
             if (weapons[current_weapon_name].CAN_REFILL == true):
@@ -637,7 +637,7 @@ Alright, now switch back to ``Target.tscn``, select the ``Target`` :ref:`StaticB
 Add the following code to ``Target.gd``:
 Add the following code to ``Target.gd``:
 
 
 ::
 ::
-    
+
     extends StaticBody
     extends StaticBody
 
 
     const TARGET_HEALTH = 40
     const TARGET_HEALTH = 40
@@ -662,12 +662,12 @@ Add the following code to ``Target.gd``:
     func _physics_process(delta):
     func _physics_process(delta):
         if target_respawn_timer > 0:
         if target_respawn_timer > 0:
             target_respawn_timer -= delta
             target_respawn_timer -= delta
-            
+
             if target_respawn_timer <= 0:
             if target_respawn_timer <= 0:
-                
+
                 for child in broken_target_holder.get_children():
                 for child in broken_target_holder.get_children():
                     child.queue_free()
                     child.queue_free()
-                
+
                 target_collision_shape.disabled = false
                 target_collision_shape.disabled = false
                 visible = true
                 visible = true
                 current_health = TARGET_HEALTH
                 current_health = TARGET_HEALTH
@@ -675,20 +675,20 @@ Add the following code to ``Target.gd``:
 
 
     func bullet_hit(damage, bullet_transform):
     func bullet_hit(damage, bullet_transform):
         current_health -= damage
         current_health -= damage
-        
+
         if current_health <= 0:
         if current_health <= 0:
             var clone = destroyed_target.instance()
             var clone = destroyed_target.instance()
             broken_target_holder.add_child(clone)
             broken_target_holder.add_child(clone)
-            
+
             for rigid in clone.get_children():
             for rigid in clone.get_children():
                 if rigid is RigidBody:
                 if rigid is RigidBody:
                     var center_in_rigid_space = broken_target_holder.global_transform.origin - rigid.global_transform.origin
                     var center_in_rigid_space = broken_target_holder.global_transform.origin - rigid.global_transform.origin
                     var direction = (rigid.transform.origin - center_in_rigid_space).normalized()
                     var direction = (rigid.transform.origin - center_in_rigid_space).normalized()
                     # Apply the impulse with some additional force (I find 12 works nicely)
                     # Apply the impulse with some additional force (I find 12 works nicely)
                     rigid.apply_impulse(center_in_rigid_space, direction * 12 * damage)
                     rigid.apply_impulse(center_in_rigid_space, direction * 12 * damage)
-            
+
             target_respawn_timer = TARGET_RESPAWN_TIME
             target_respawn_timer = TARGET_RESPAWN_TIME
-            
+
             target_collision_shape.disabled = true
             target_collision_shape.disabled = true
             visible = false
             visible = false
 
 

+ 34 - 34
tutorials/3d/fps_tutorial/part_one.rst

@@ -127,7 +127,7 @@ the ``X`` axis.
 .. note:: If we did not use ``Rotation_helper`` then we'd likely have cases where we are rotating
 .. note:: If we did not use ``Rotation_helper`` then we'd likely have cases where we are rotating
           both the ``X`` and ``Y`` axes at the same time. This can lead to undesirable results, as we then
           both the ``X`` and ``Y`` axes at the same time. This can lead to undesirable results, as we then
           could rotate on all three axes in some cases.
           could rotate on all three axes in some cases.
-          
+
           See :ref:`using transforms <doc_using_transforms>` for more information
           See :ref:`using transforms <doc_using_transforms>` for more information
 
 
 _________
 _________
@@ -148,34 +148,34 @@ Add the following code to ``Player.gd``:
     const ACCEL = 4.5
     const ACCEL = 4.5
 
 
     var dir = Vector3()
     var dir = Vector3()
-    
+
     const DEACCEL= 16
     const DEACCEL= 16
     const MAX_SLOPE_ANGLE = 40
     const MAX_SLOPE_ANGLE = 40
-    
+
     var camera
     var camera
     var rotation_helper
     var rotation_helper
-    
+
     var MOUSE_SENSITIVITY = 0.05
     var MOUSE_SENSITIVITY = 0.05
-    
+
     func _ready():
     func _ready():
         camera = $Rotation_Helper/Camera
         camera = $Rotation_Helper/Camera
         rotation_helper = $Rotation_Helper
         rotation_helper = $Rotation_Helper
-        
+
         Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
         Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
-    
+
     func _physics_process(delta):
     func _physics_process(delta):
         process_input(delta)
         process_input(delta)
         process_movement(delta)
         process_movement(delta)
-    
+
     func process_input(delta):
     func process_input(delta):
-        
+
         # ----------------------------------
         # ----------------------------------
         # Walking
         # Walking
         dir = Vector3()
         dir = Vector3()
         var cam_xform = camera.get_global_transform()
         var cam_xform = camera.get_global_transform()
-        
+
         var input_movement_vector = Vector2()
         var input_movement_vector = Vector2()
-        
+
         if Input.is_action_pressed("movement_forward"):
         if Input.is_action_pressed("movement_forward"):
             input_movement_vector.y += 1
             input_movement_vector.y += 1
         if Input.is_action_pressed("movement_backward"):
         if Input.is_action_pressed("movement_backward"):
@@ -184,20 +184,20 @@ Add the following code to ``Player.gd``:
             input_movement_vector.x -= 1
             input_movement_vector.x -= 1
         if Input.is_action_pressed("movement_right"):
         if Input.is_action_pressed("movement_right"):
             input_movement_vector.x += 1
             input_movement_vector.x += 1
-        
+
         input_movement_vector = input_movement_vector.normalized()
         input_movement_vector = input_movement_vector.normalized()
-        
+
         dir += -cam_xform.basis.z.normalized() * input_movement_vector.y
         dir += -cam_xform.basis.z.normalized() * input_movement_vector.y
         dir += cam_xform.basis.x.normalized() * input_movement_vector.x
         dir += cam_xform.basis.x.normalized() * input_movement_vector.x
         # ----------------------------------
         # ----------------------------------
-        
+
         # ----------------------------------
         # ----------------------------------
         # Jumping
         # Jumping
         if is_on_floor():
         if is_on_floor():
             if Input.is_action_just_pressed("movement_jump"):
             if Input.is_action_just_pressed("movement_jump"):
                 vel.y = JUMP_SPEED
                 vel.y = JUMP_SPEED
         # ----------------------------------
         # ----------------------------------
-        
+
         # ----------------------------------
         # ----------------------------------
         # Capturing/Freeing the cursor
         # Capturing/Freeing the cursor
         if Input.is_action_just_pressed("ui_cancel"):
         if Input.is_action_just_pressed("ui_cancel"):
@@ -206,35 +206,35 @@ Add the following code to ``Player.gd``:
             else:
             else:
                 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
                 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
         # ----------------------------------
         # ----------------------------------
-        
+
     func process_movement(delta):
     func process_movement(delta):
         dir.y = 0
         dir.y = 0
         dir = dir.normalized()
         dir = dir.normalized()
-        
+
         vel.y += delta*GRAVITY
         vel.y += delta*GRAVITY
-        
+
         var hvel = vel
         var hvel = vel
         hvel.y = 0
         hvel.y = 0
-        
+
         var target = dir
         var target = dir
         target *= MAX_SPEED
         target *= MAX_SPEED
-        
+
         var accel
         var accel
         if dir.dot(hvel) > 0:
         if dir.dot(hvel) > 0:
             accel = ACCEL
             accel = ACCEL
         else:
         else:
             accel = DEACCEL
             accel = DEACCEL
-        
+
         hvel = hvel.linear_interpolate(target, accel*delta)
         hvel = hvel.linear_interpolate(target, accel*delta)
         vel.x = hvel.x
         vel.x = hvel.x
         vel.z = hvel.z
         vel.z = hvel.z
         vel = move_and_slide(vel,Vector3(0,1,0), 0.05, 4, deg2rad(MAX_SLOPE_ANGLE))
         vel = move_and_slide(vel,Vector3(0,1,0), 0.05, 4, deg2rad(MAX_SLOPE_ANGLE))
-        
+
     func _input(event):
     func _input(event):
         if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
         if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
             rotation_helper.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
             rotation_helper.rotate_x(deg2rad(event.relative.y * MOUSE_SENSITIVITY))
             self.rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
             self.rotate_y(deg2rad(event.relative.x * MOUSE_SENSITIVITY * -1))
-            
+
             var camera_rot = rotation_helper.rotation_degrees
             var camera_rot = rotation_helper.rotation_degrees
             camera_rot.x = clamp(camera_rot.x, -70, 70)
             camera_rot.x = clamp(camera_rot.x, -70, 70)
             rotation_helper.rotation_degrees = camera_rot
             rotation_helper.rotation_degrees = camera_rot
@@ -243,9 +243,9 @@ This is a lot of code, so let's break it down function by function:
 
 
 .. tip:: While copy and pasting code is ill advised, as you can learn a lot from manually typing the code in, you can
 .. tip:: While copy and pasting code is ill advised, as you can learn a lot from manually typing the code in, you can
          copy and paste the code from this page directly into the script editor.
          copy and paste the code from this page directly into the script editor.
-         
+
          If you do this, all of the code copied will be using spaces instead of tabs.
          If you do this, all of the code copied will be using spaces instead of tabs.
-         
+
          To convert the spaces to tabs in the script editor, click the "edit" menu and select "Convert Indent To Tabs".
          To convert the spaces to tabs in the script editor, click the "edit" menu and select "Convert Indent To Tabs".
          This will convert all of the spaces into tabs. You can select "Convert Indent To Spaces" to convert t back into spaces.
          This will convert all of the spaces into tabs. You can select "Convert Indent To Spaces" to convert t back into spaces.
 
 
@@ -275,7 +275,7 @@ increasing ``JUMP_SPEED`` you can get a more 'floaty' feeling character.
 Feel free to experiment!
 Feel free to experiment!
 
 
 .. note:: You may have noticed that ``MOUSE_SENSITIVITY`` is written in all caps like the other constants, but ``MOUSE_SENSITIVITY`` is not a constant.
 .. note:: You may have noticed that ``MOUSE_SENSITIVITY`` is written in all caps like the other constants, but ``MOUSE_SENSITIVITY`` is not a constant.
-          
+
           The reason behind this is we want to treat it like a constant variable (a variable that cannot change) throughout our script, but we want to be
           The reason behind this is we want to treat it like a constant variable (a variable that cannot change) throughout our script, but we want to be
           able to change the value later when we add customizable settings. So, in an effort to remind ourselves to treat it like a constant, it's named in all caps.
           able to change the value later when we add customizable settings. So, in an effort to remind ourselves to treat it like a constant, it's named in all caps.
 
 
@@ -543,7 +543,7 @@ First we need a few more class variables in our player script:
     const MAX_SPRINT_SPEED = 30
     const MAX_SPRINT_SPEED = 30
     const SPRINT_ACCEL = 18
     const SPRINT_ACCEL = 18
     var is_sprinting = false
     var is_sprinting = false
-    
+
     var flashlight
     var flashlight
 
 
 All of the sprinting variables work exactly the same as the non sprinting variables with
 All of the sprinting variables work exactly the same as the non sprinting variables with
@@ -555,7 +555,7 @@ we will be using to hold the player's flash light node.
 Now we need to add a few lines of code, starting in ``_ready``. Add the following to ``_ready``:
 Now we need to add a few lines of code, starting in ``_ready``. Add the following to ``_ready``:
 
 
 ::
 ::
-    
+
     flashlight = $Rotation_Helper/Flashlight
     flashlight = $Rotation_Helper/Flashlight
 
 
 This gets the flash light node and assigns it to the ``flashlight`` variable.
 This gets the flash light node and assigns it to the ``flashlight`` variable.
@@ -565,7 +565,7 @@ _________
 Now we need to change some of the code in ``process_input``. Add the following somewhere in ``process_input``:
 Now we need to change some of the code in ``process_input``. Add the following somewhere in ``process_input``:
 
 
 ::
 ::
-    
+
     # ----------------------------------
     # ----------------------------------
     # Sprinting
     # Sprinting
     if Input.is_action_pressed("movement_sprint"):
     if Input.is_action_pressed("movement_sprint"):
@@ -573,7 +573,7 @@ Now we need to change some of the code in ``process_input``. Add the following s
     else:
     else:
         is_sprinting = false
         is_sprinting = false
     # ----------------------------------
     # ----------------------------------
-    
+
     # ----------------------------------
     # ----------------------------------
     # Turning the flashlight on/off
     # Turning the flashlight on/off
     if Input.is_action_just_pressed("flashlight"):
     if Input.is_action_just_pressed("flashlight"):
@@ -597,26 +597,26 @@ _________
 Now we need to change a couple things in ``process_movement``. First, replace ``target *= MAX_SPEED`` with the following:
 Now we need to change a couple things in ``process_movement``. First, replace ``target *= MAX_SPEED`` with the following:
 
 
 ::
 ::
-    
+
     if is_sprinting:
     if is_sprinting:
         target *= MAX_SPRINT_SPEED
         target *= MAX_SPRINT_SPEED
     else:
     else:
         target *= MAX_SPEED
         target *= MAX_SPEED
 
 
 Now instead of always multiplying ``target`` by ``MAX_SPEED``, we first check to see if the player is sprinting or not.
 Now instead of always multiplying ``target`` by ``MAX_SPEED``, we first check to see if the player is sprinting or not.
-If the player is sprinting, we instead multiply ``target`` by ``MAX_SPRINT_SPEED``. 
+If the player is sprinting, we instead multiply ``target`` by ``MAX_SPRINT_SPEED``.
 
 
 Now all that's left is changing the acceleration when sprinting. Change ``accel = ACCEL`` to the following:
 Now all that's left is changing the acceleration when sprinting. Change ``accel = ACCEL`` to the following:
 
 
 ::
 ::
-    
+
     if is_sprinting:
     if is_sprinting:
         accel = SPRINT_ACCEL
         accel = SPRINT_ACCEL
     else:
     else:
         accel = ACCEL
         accel = ACCEL
 
 
 
 
-Now when the player is sprinting we'll use ``SPRINT_ACCEL`` instead of ``ACCEL``, which will accelerate the player faster.        
+Now when the player is sprinting we'll use ``SPRINT_ACCEL`` instead of ``ACCEL``, which will accelerate the player faster.
 
 
 _________
 _________
 
 

+ 58 - 58
tutorials/3d/fps_tutorial/part_six.rst

@@ -15,7 +15,7 @@ This is the last part of the FPS tutorial, by the end of this you will have a so
 
 
 .. note:: You are assumed to have finished :ref:`doc_fps_tutorial_part_five` before moving on to this part of the tutorial.
 .. note:: You are assumed to have finished :ref:`doc_fps_tutorial_part_five` before moving on to this part of the tutorial.
           The finished project from :ref:`doc_fps_tutorial_part_four` will be the starting project for part 6
           The finished project from :ref:`doc_fps_tutorial_part_four` will be the starting project for part 6
-          
+
 Let's get started!
 Let's get started!
 
 
 Adding the main menu
 Adding the main menu
@@ -50,24 +50,24 @@ Select ``Main_Menu`` (the root node) and create a new script called ``Main_Menu.
         start_menu = $Start_Menu
         start_menu = $Start_Menu
         level_select_menu = $Level_Select_Menu
         level_select_menu = $Level_Select_Menu
         options_menu = $Options_Menu
         options_menu = $Options_Menu
-        
+
         $Start_Menu/Button_Start.connect("pressed", self, "start_menu_button_pressed", ["start"])
         $Start_Menu/Button_Start.connect("pressed", self, "start_menu_button_pressed", ["start"])
         $Start_Menu/Button_Open_Godot.connect("pressed", self, "start_menu_button_pressed", ["open_godot"])
         $Start_Menu/Button_Open_Godot.connect("pressed", self, "start_menu_button_pressed", ["open_godot"])
         $Start_Menu/Button_Options.connect("pressed", self, "start_menu_button_pressed", ["options"])
         $Start_Menu/Button_Options.connect("pressed", self, "start_menu_button_pressed", ["options"])
         $Start_Menu/Button_Quit.connect("pressed", self, "start_menu_button_pressed", ["quit"])
         $Start_Menu/Button_Quit.connect("pressed", self, "start_menu_button_pressed", ["quit"])
-        
+
         $Level_Select_Menu/Button_Back.connect("pressed", self, "level_select_menu_button_pressed", ["back"])
         $Level_Select_Menu/Button_Back.connect("pressed", self, "level_select_menu_button_pressed", ["back"])
         $Level_Select_Menu/Button_Level_Testing_Area.connect("pressed", self, "level_select_menu_button_pressed", ["testing_scene"])
         $Level_Select_Menu/Button_Level_Testing_Area.connect("pressed", self, "level_select_menu_button_pressed", ["testing_scene"])
         $Level_Select_Menu/Button_Level_Space.connect("pressed", self, "level_select_menu_button_pressed", ["space_level"])
         $Level_Select_Menu/Button_Level_Space.connect("pressed", self, "level_select_menu_button_pressed", ["space_level"])
         $Level_Select_Menu/Button_Level_Ruins.connect("pressed", self, "level_select_menu_button_pressed", ["ruins_level"])
         $Level_Select_Menu/Button_Level_Ruins.connect("pressed", self, "level_select_menu_button_pressed", ["ruins_level"])
-        
+
         $Options_Menu/Button_Back.connect("pressed", self, "options_menu_button_pressed", ["back"])
         $Options_Menu/Button_Back.connect("pressed", self, "options_menu_button_pressed", ["back"])
         $Options_Menu/Button_Fullscreen.connect("pressed", self, "options_menu_button_pressed", ["fullscreen"])
         $Options_Menu/Button_Fullscreen.connect("pressed", self, "options_menu_button_pressed", ["fullscreen"])
         $Options_Menu/Check_Button_VSync.connect("pressed", self, "options_menu_button_pressed", ["vsync"])
         $Options_Menu/Check_Button_VSync.connect("pressed", self, "options_menu_button_pressed", ["vsync"])
         $Options_Menu/Check_Button_Debug.connect("pressed", self, "options_menu_button_pressed", ["debug"])
         $Options_Menu/Check_Button_Debug.connect("pressed", self, "options_menu_button_pressed", ["debug"])
-        
+
         Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
         Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
-        
+
         var globals = get_node("/root/Globals")
         var globals = get_node("/root/Globals")
         $Options_Menu/HSlider_Mouse_Sensitivity.value = globals.mouse_sensitivity
         $Options_Menu/HSlider_Mouse_Sensitivity.value = globals.mouse_sensitivity
         $Options_Menu/HSlider_Joypad_Sensitivity.value = globals.joypad_sensitivity
         $Options_Menu/HSlider_Joypad_Sensitivity.value = globals.joypad_sensitivity
@@ -162,7 +162,7 @@ In ``level_select_menu_button_pressed``, we check to see which button is pressed
 
 
 If the ``back`` button has been pressed, we change the currently visible panels to return to the main menu.
 If the ``back`` button has been pressed, we change the currently visible panels to return to the main menu.
 
 
-If one of the scene changing buttons are pressed, we fist call ``set_mouse_and_joypad_sensitivity`` so the singleton (``Globals.gd``) has the values from the :ref:`HSlider 
+If one of the scene changing buttons are pressed, we fist call ``set_mouse_and_joypad_sensitivity`` so the singleton (``Globals.gd``) has the values from the :ref:`HSlider
 <class_HSlider>` nodes.
 <class_HSlider>` nodes.
 Then we tell the singleton to change nodes using its ``load_new_scene`` function, passing in the file path of the scene the player has selected.
 Then we tell the singleton to change nodes using its ``load_new_scene`` function, passing in the file path of the scene the player has selected.
 
 
@@ -303,12 +303,12 @@ Open up ``Globals.gd`` and add the following class variables:
 
 
     # ------------------------------------
     # ------------------------------------
     # All of the GUI/UI related variables
     # All of the GUI/UI related variables
-    
+
     var canvas_layer = null
     var canvas_layer = null
-    
+
     const DEBUG_DISPLAY_SCENE = preload("res://Debug_Display.tscn")
     const DEBUG_DISPLAY_SCENE = preload("res://Debug_Display.tscn")
     var debug_display = null
     var debug_display = null
-    
+
     # ------------------------------------
     # ------------------------------------
 
 
 * ``canvas_layer``: A canvas layer so the GUI/UI created in ``Globals.gd`` is always drawn on top.
 * ``canvas_layer``: A canvas layer so the GUI/UI created in ``Globals.gd`` is always drawn on top.
@@ -336,7 +336,7 @@ This is because nodes will not be freed/destroyed when you change scene, meaning
 instancing/spawning lots of nodes and you are not freeing them.
 instancing/spawning lots of nodes and you are not freeing them.
 
 
 ______
 ______
-        
+
 Now we need to add ``set_debug_display`` to ``Globals.gd``:
 Now we need to add ``set_debug_display`` to ``Globals.gd``:
 
 
 ::
 ::
@@ -350,7 +350,7 @@ Now we need to add ``set_debug_display`` to ``Globals.gd``:
             if debug_display == null:
             if debug_display == null:
                 debug_display = DEBUG_DISPLAY_SCENE.instance()
                 debug_display = DEBUG_DISPLAY_SCENE.instance()
                 canvas_layer.add_child(debug_display)
                 canvas_layer.add_child(debug_display)
-                
+
 Let's go over what's happening.
 Let's go over what's happening.
 
 
 First we check to see if ``Globals.gd`` is trying to turn on the debug display, or turn it off.
 First we check to see if ``Globals.gd`` is trying to turn on the debug display, or turn it off.
@@ -409,16 +409,16 @@ Add the following to ``_process``:
         if Input.is_action_just_pressed("ui_cancel"):
         if Input.is_action_just_pressed("ui_cancel"):
             if popup == null:
             if popup == null:
                 popup = POPUP_SCENE.instance()
                 popup = POPUP_SCENE.instance()
-                
+
                 popup.get_node("Button_quit").connect("pressed", self, "popup_quit")
                 popup.get_node("Button_quit").connect("pressed", self, "popup_quit")
                 popup.connect("popup_hide", self, "popup_closed")
                 popup.connect("popup_hide", self, "popup_closed")
                 popup.get_node("Button_resume").connect("pressed", self, "popup_closed")
                 popup.get_node("Button_resume").connect("pressed", self, "popup_closed")
-                
+
                 canvas_layer.add_child(popup)
                 canvas_layer.add_child(popup)
                 popup.popup_centered()
                 popup.popup_centered()
-                
+
                 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
                 Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
-                
+
                 get_tree().paused = true
                 get_tree().paused = true
 
 
 Let's go over what's happening here.
 Let's go over what's happening here.
@@ -458,9 +458,9 @@ Add the following to ``Globals.gd``:
         if popup != null:
         if popup != null:
             popup.queue_free()
             popup.queue_free()
             popup = null
             popup = null
-            
+
 ``popup_closed`` will resume the game and destroy the pop up if there is one.
 ``popup_closed`` will resume the game and destroy the pop up if there is one.
-    
+
 ``popup_quit`` is similar, but we're also making sure the mouse is visible and changing scenes to the title screen.
 ``popup_quit`` is similar, but we're also making sure the mouse is visible and changing scenes to the title screen.
 
 
 Add the following to ``Globals.gd``:
 Add the following to ``Globals.gd``:
@@ -477,7 +477,7 @@ Add the following to ``Globals.gd``:
             popup = null
             popup = null
 
 
         load_new_scene(MAIN_MENU_PATH)
         load_new_scene(MAIN_MENU_PATH)
-        
+
 ``popup_quit`` will resume the game, set the mouse mode to ``MOUSE_MODE_VISIBLE`` to ensure the mouse is visible in the main menu, destroy
 ``popup_quit`` will resume the game, set the mouse mode to ``MOUSE_MODE_VISIBLE`` to ensure the mouse is visible in the main menu, destroy
 the pop up if there is one, and change scenes to the main menu.
 the pop up if there is one, and change scenes to the main menu.
 
 
@@ -530,7 +530,7 @@ Open up ``Player.gd`` and add the following class variables:
     const RESPAWN_TIME = 4
     const RESPAWN_TIME = 4
     var dead_time = 0
     var dead_time = 0
     var is_dead = false
     var is_dead = false
-    
+
     var globals
     var globals
 
 
 * ``RESPAWN_TIME``: The amount of time (in seconds) it takes to respawn.
 * ``RESPAWN_TIME``: The amount of time (in seconds) it takes to respawn.
@@ -546,15 +546,15 @@ We now need to add a couple lines to ``_ready``, so we can use ``Globals.gd`` in
 
 
     globals = get_node("/root/Globals")
     globals = get_node("/root/Globals")
     global_transform.origin = globals.get_respawn_position()
     global_transform.origin = globals.get_respawn_position()
-    
+
 
 
 Now we're getting the ``Globals.gd`` singleton and assigning it to ``globals``. We also set the player's global position
 Now we're getting the ``Globals.gd`` singleton and assigning it to ``globals``. We also set the player's global position
 by setting the origin in the player's global :ref:`Transform <class_Transform>` to the position returned by ``globals.get_respawn_position``.
 by setting the origin in the player's global :ref:`Transform <class_Transform>` to the position returned by ``globals.get_respawn_position``.
 
 
 .. note:: Don't worry, we will be adding ``get_respawn_position`` further below!
 .. note:: Don't worry, we will be adding ``get_respawn_position`` further below!
-    
+
 ______
 ______
-    
+
 Next we need to make a few changes to ``physics_process``. Change ``physics_processing`` to the following:
 Next we need to make a few changes to ``physics_process``. Change ``physics_processing`` to the following:
 
 
 ::
 ::
@@ -586,58 +586,58 @@ Let's add ``process_respawn``. Add the following to ``Player.gd``:
 ::
 ::
 
 
     func process_respawn(delta):
     func process_respawn(delta):
-    
+
         # If we just died
         # If we just died
         if health <= 0 and !is_dead:
         if health <= 0 and !is_dead:
             $Body_CollisionShape.disabled = true
             $Body_CollisionShape.disabled = true
             $Feet_CollisionShape.disabled = true
             $Feet_CollisionShape.disabled = true
-            
+
             changing_weapon = true
             changing_weapon = true
             changing_weapon_name = "UNARMED"
             changing_weapon_name = "UNARMED"
-            
+
             $HUD/Death_Screen.visible = true
             $HUD/Death_Screen.visible = true
-            
+
             $HUD/Panel.visible = false
             $HUD/Panel.visible = false
             $HUD/Crosshair.visible = false
             $HUD/Crosshair.visible = false
-            
+
             dead_time = RESPAWN_TIME
             dead_time = RESPAWN_TIME
             is_dead = true
             is_dead = true
-            
+
             if grabbed_object != null:
             if grabbed_object != null:
                 grabbed_object.mode = RigidBody.MODE_RIGID
                 grabbed_object.mode = RigidBody.MODE_RIGID
                 grabbed_object.apply_impulse(Vector3(0,0,0), -camera.global_transform.basis.z.normalized() * OBJECT_THROW_FORCE / 2)
                 grabbed_object.apply_impulse(Vector3(0,0,0), -camera.global_transform.basis.z.normalized() * OBJECT_THROW_FORCE / 2)
-                
+
                 grabbed_object.collision_layer = 1
                 grabbed_object.collision_layer = 1
                 grabbed_object.collision_mask = 1
                 grabbed_object.collision_mask = 1
-                
+
                 grabbed_object = null
                 grabbed_object = null
-        
+
         if is_dead:
         if is_dead:
             dead_time -= delta
             dead_time -= delta
-            
+
             var dead_time_pretty = str(dead_time).left(3)
             var dead_time_pretty = str(dead_time).left(3)
             $HUD/Death_Screen/Label.text = "You died\n" + dead_time_pretty + " seconds till respawn"
             $HUD/Death_Screen/Label.text = "You died\n" + dead_time_pretty + " seconds till respawn"
-            
+
             if dead_time <= 0:
             if dead_time <= 0:
                 global_transform.origin = globals.get_respawn_position()
                 global_transform.origin = globals.get_respawn_position()
-                
+
                 $Body_CollisionShape.disabled = false
                 $Body_CollisionShape.disabled = false
                 $Feet_CollisionShape.disabled = false
                 $Feet_CollisionShape.disabled = false
-                
+
                 $HUD/Death_Screen.visible = false
                 $HUD/Death_Screen.visible = false
-                
+
                 $HUD/Panel.visible = true
                 $HUD/Panel.visible = true
                 $HUD/Crosshair.visible = true
                 $HUD/Crosshair.visible = true
-                
+
                 for weapon in weapons:
                 for weapon in weapons:
                     var weapon_node = weapons[weapon]
                     var weapon_node = weapons[weapon]
                     if weapon_node != null:
                     if weapon_node != null:
                         weapon_node.reset_weapon()
                         weapon_node.reset_weapon()
-                
+
                 health = 100
                 health = 100
                 grenade_amounts = {"Grenade":2, "Sticky Grenade":2}
                 grenade_amounts = {"Grenade":2, "Sticky Grenade":2}
                 current_grenade = "Grenade"
                 current_grenade = "Grenade"
-                
+
                 is_dead = false
                 is_dead = false
 
 
 Let's go through what this function is doing.
 Let's go through what this function is doing.
@@ -792,7 +792,7 @@ Now all we need is a way to set the respawn points. Open up ``Ruins_Level.tscn``
     func _ready():
     func _ready():
         var globals = get_node("/root/Globals")
         var globals = get_node("/root/Globals")
         globals.respawn_points = get_children()
         globals.respawn_points = get_children()
-        
+
 Now when a node with ``Respawn_Point_Setter.gd`` has its ``_ready`` function called, all of the children
 Now when a node with ``Respawn_Point_Setter.gd`` has its ``_ready`` function called, all of the children
 nodes of the node with ``Respawn_Point_Setter.gd``, ``Spawn_Points`` in the case of ``Ruins_Level.tscn``, will be added
 nodes of the node with ``Respawn_Point_Setter.gd``, ``Spawn_Points`` in the case of ``Ruins_Level.tscn``, will be added
 to ``respawn_points`` in ``Globals.gd``.
 to ``respawn_points`` in ``Globals.gd``.
@@ -806,7 +806,7 @@ Now when the player dies, they will respawn after waiting ``4`` seconds!
 
 
 .. note:: No spawn points are already set up for any of the levels besides ``Ruins_Level.tscn``!
 .. note:: No spawn points are already set up for any of the levels besides ``Ruins_Level.tscn``!
           Adding spawn points to ``Space_Level.tscn`` is left as an exercise for the reader.
           Adding spawn points to ``Space_Level.tscn`` is left as an exercise for the reader.
-                
+
 Writing a sound system we can use anywhere
 Writing a sound system we can use anywhere
 ------------------------------------------
 ------------------------------------------
 
 
@@ -826,7 +826,7 @@ First, open up ``SimpleAudioPlayer.gd`` and change it to the following:
         audio_node = $Audio_Stream_Player
         audio_node = $Audio_Stream_Player
         audio_node.connect("finished", self, "sound_finished")
         audio_node.connect("finished", self, "sound_finished")
         audio_node.stop()
         audio_node.stop()
-        
+
         globals = get_node("/root/Globals")
         globals = get_node("/root/Globals")
 
 
 
 
@@ -836,13 +836,13 @@ First, open up ``SimpleAudioPlayer.gd`` and change it to the following:
             globals.created_audio.remove(globals.created_audio.find(self))
             globals.created_audio.remove(globals.created_audio.find(self))
             queue_free()
             queue_free()
             return
             return
-        
+
         audio_node.stream = audio_stream
         audio_node.stream = audio_stream
-        
+
         # If you are using a AudioPlayer3D, then uncomment these lines to set the position.
         # If you are using a AudioPlayer3D, then uncomment these lines to set the position.
         #if position != null:
         #if position != null:
         #    audio_node.global_transform.origin = position
         #    audio_node.global_transform.origin = position
-        
+
         audio_node.play(0.0)
         audio_node.play(0.0)
 
 
 
 
@@ -854,7 +854,7 @@ First, open up ``SimpleAudioPlayer.gd`` and change it to the following:
             audio_node.stop()
             audio_node.stop()
             queue_free()
             queue_free()
 
 
-            
+
 There are several changes from the old version, first and foremost being we are no longer storing the sound files in ``SimpleAudioPlayer.gd`` anymore.
 There are several changes from the old version, first and foremost being we are no longer storing the sound files in ``SimpleAudioPlayer.gd`` anymore.
 This is much better for performance since we're no longer loading each audio clip when we create a sound, but instead we are forcing an audio stream to be passed
 This is much better for performance since we're no longer loading each audio clip when we create a sound, but instead we are forcing an audio stream to be passed
 in to ``play_sound``.
 in to ``play_sound``.
@@ -909,17 +909,17 @@ Lets go over these global variables.
 
 
 .. note:: If you want to add additional audio, you need to add it to ``audio_clips``. No audio files are provided in this tutorial,
 .. note:: If you want to add additional audio, you need to add it to ``audio_clips``. No audio files are provided in this tutorial,
           so you will have to provide your own.
           so you will have to provide your own.
-          
+
           One site I'd recommend is **GameSounds.xyz**.
           One site I'd recommend is **GameSounds.xyz**.
           I'm using the Gamemaster audio gun sound pack included in the Sonniss' GDC Game Audio bundle for 2017.
           I'm using the Gamemaster audio gun sound pack included in the Sonniss' GDC Game Audio bundle for 2017.
           The tracks I've used (with some minor editing) are as follows:
           The tracks I've used (with some minor editing) are as follows:
-          
+
           * gun_revolver_pistol_shot_04,
           * gun_revolver_pistol_shot_04,
           * gun_semi_auto_rifle_cock_02,
           * gun_semi_auto_rifle_cock_02,
           * gun_submachine_auto_shot_00_automatic_preview_01
           * gun_submachine_auto_shot_00_automatic_preview_01
 
 
 ______
 ______
-          
+
 Now we need to add a new function called ``play_sound`` to ``Globals.gd``:
 Now we need to add a new function called ``play_sound`` to ``Globals.gd``:
 
 
 ::
 ::
@@ -928,12 +928,12 @@ Now we need to add a new function called ``play_sound`` to ``Globals.gd``:
         if audio_clips.has(sound_name):
         if audio_clips.has(sound_name):
             var new_audio = SIMPLE_AUDIO_PLAYER_SCENE.instance()
             var new_audio = SIMPLE_AUDIO_PLAYER_SCENE.instance()
             new_audio.should_loop = loop_sound
             new_audio.should_loop = loop_sound
-            
+
             add_child(new_audio)
             add_child(new_audio)
             created_audio.append(new_audio)
             created_audio.append(new_audio)
-            
+
             new_audio.play_sound(audio_clips[sound_name], sound_position)
             new_audio.play_sound(audio_clips[sound_name], sound_position)
-        
+
         else:
         else:
             print ("ERROR: cannot play sound that does not exist in audio_clips!")
             print ("ERROR: cannot play sound that does not exist in audio_clips!")
 
 
@@ -961,7 +961,7 @@ Add the following to ``load_new_scene``:
         if (sound != null):
         if (sound != null):
             sound.queue_free()
             sound.queue_free()
     created_audio.clear()
     created_audio.clear()
-    
+
 Now before ``Globals.gd`` changes scenes, it goes through each simple audio player in ``created_sounds`` and frees/destroys them. Once ``Globals.gd`` has gone through
 Now before ``Globals.gd`` changes scenes, it goes through each simple audio player in ``created_sounds`` and frees/destroys them. Once ``Globals.gd`` has gone through
 all of the sounds in ``created_audio``, we clear ``created_audio`` so it no longer holds any references to any (noew freed/destroyed) simple audio players.
 all of the sounds in ``created_audio``, we clear ``created_audio`` so it no longer holds any references to any (noew freed/destroyed) simple audio players.
 
 
@@ -1010,11 +1010,11 @@ At this point you have a good base to build more complicated FPS games.
 
 
           Other than that, the source is exactly the same, just with helpful comments explaining what
           Other than that, the source is exactly the same, just with helpful comments explaining what
           each part does.
           each part does.
-             
+
 .. tip:: The finished project source is hosted on Github as well: https://github.com/TwistedTwigleg/Godot_FPS_Tutorial
 .. tip:: The finished project source is hosted on Github as well: https://github.com/TwistedTwigleg/Godot_FPS_Tutorial
-         
+
          **Please note that the code in Github may or may not be in sync with the tutorial in the documentation**.
          **Please note that the code in Github may or may not be in sync with the tutorial in the documentation**.
-         
+
          The code in the documentation is likely better managed and/or more up to date.
          The code in the documentation is likely better managed and/or more up to date.
          If you are unsure on which to use, use the project(s) provided in the documentation as they are maintained by the Godot community.
          If you are unsure on which to use, use the project(s) provided in the documentation as they are maintained by the Godot community.
 
 
@@ -1024,7 +1024,7 @@ All assets provided in the started assets (unless otherwise noted) were **origin
 All original assets provided for this tutorial are released under the ``MIT`` license.
 All original assets provided for this tutorial are released under the ``MIT`` license.
 
 
 Feel free to use these assets however you want! All original assets belong to the Godot community, with the other assets belonging to those listed below:
 Feel free to use these assets however you want! All original assets belong to the Godot community, with the other assets belonging to those listed below:
-          
+
 The skybox is created by **StumpyStrust** and can be found at OpenGameArt.org. https://opengameart.org/content/space-skyboxes-0
 The skybox is created by **StumpyStrust** and can be found at OpenGameArt.org. https://opengameart.org/content/space-skyboxes-0
 . The skybox is licensed under the ``CC0`` license.
 . The skybox is licensed under the ``CC0`` license.
 
 

+ 56 - 56
tutorials/3d/fps_tutorial/part_three.rst

@@ -40,34 +40,34 @@ Follow the instructions below for either (or both) of the scenes you want to use
  .. code-tab:: gdscript Space_Level.tscn
  .. code-tab:: gdscript Space_Level.tscn
 
 
     Expand "Other_Objects" and then expand "Physics_Objects".
     Expand "Other_Objects" and then expand "Physics_Objects".
-    
+
     Expand one of the "Barrel_Group" nodes and then select "Barrel_Rigid_Body" and open it using
     Expand one of the "Barrel_Group" nodes and then select "Barrel_Rigid_Body" and open it using
     the "Open in Editor" button.
     the "Open in Editor" button.
     This will bring you to the "Barrel_Rigid_Body" scene. From there select the root node and
     This will bring you to the "Barrel_Rigid_Body" scene. From there select the root node and
     scroll the inspector down to the bottom.
     scroll the inspector down to the bottom.
     Select the drop down arrow under the "Node" tab, and then select "Load". Navigate to
     Select the drop down arrow under the "Node" tab, and then select "Load". Navigate to
     "RigidBody_hit_test.gd" and select "Open".
     "RigidBody_hit_test.gd" and select "Open".
-    
+
     Return back to "Space_Level.tscn".
     Return back to "Space_Level.tscn".
-    
+
     Expand one of the "Box_Group" nodes and then select "Crate_Rigid_Body" and open it using the
     Expand one of the "Box_Group" nodes and then select "Crate_Rigid_Body" and open it using the
     "Open in Editor" button.
     "Open in Editor" button.
     This will bring you to the "Crate_Rigid_Body" scene. From there select the root node and
     This will bring you to the "Crate_Rigid_Body" scene. From there select the root node and
     scroll the inspector down to the bottom.
     scroll the inspector down to the bottom.
     Select the drop down arrow under the "Node" tab, and then select "Load". Navigate to
     Select the drop down arrow under the "Node" tab, and then select "Load". Navigate to
     "RigidBody_hit_test.gd" and select "Open".
     "RigidBody_hit_test.gd" and select "Open".
-    
+
     Return back to "Space_Level.tscn".
     Return back to "Space_Level.tscn".
-    
- 
+
+
  .. code-tab:: gdscript Ruins_Level.tscn
  .. code-tab:: gdscript Ruins_Level.tscn
 
 
     Expand "Misc_Objects" and then expand "Physics_Objects".
     Expand "Misc_Objects" and then expand "Physics_Objects".
-    
+
     Select all of the "Stone_Cube" RigidBodies and then in the inspector scroll down to the bottom.
     Select all of the "Stone_Cube" RigidBodies and then in the inspector scroll down to the bottom.
     Select the drop down arrow under the "Node" tab, and then select "Load". Navigate to
     Select the drop down arrow under the "Node" tab, and then select "Load". Navigate to
     "RigidBody_hit_test.gd" and select "Open".
     "RigidBody_hit_test.gd" and select "Open".
-    
+
     Return back to "Ruins_Level.tscn".
     Return back to "Ruins_Level.tscn".
 
 
 Now you can fire at all of the rigid bodies in either level and they will react to bullets hitting them!
 Now you can fire at all of the rigid bodies in either level and they will react to bullets hitting them!
@@ -82,7 +82,7 @@ First we need to define a few variables in each of our weapon scripts.
 Open up ``Weapon_Pistol.gd`` and add the following class variables:
 Open up ``Weapon_Pistol.gd`` and add the following class variables:
 
 
 ::
 ::
-    
+
     var ammo_in_weapon = 10
     var ammo_in_weapon = 10
     var spare_ammo = 20
     var spare_ammo = 20
     const AMMO_IN_MAG = 10
     const AMMO_IN_MAG = 10
@@ -104,14 +104,14 @@ Now we need to add ammo for both the rifle and the knife.
 
 
 .. note:: You may be wondering why we are adding ammo for the knife given it does not consume any ammunition.
 .. note:: You may be wondering why we are adding ammo for the knife given it does not consume any ammunition.
           The reason we want to add ammo to the knife is so we have a consistent interface for all of our weapons.
           The reason we want to add ammo to the knife is so we have a consistent interface for all of our weapons.
-          
+
           If we did not add ammo variables for the knife, we would have to add checks for the knife. By adding the ammo
           If we did not add ammo variables for the knife, we would have to add checks for the knife. By adding the ammo
           variables to the knife, we don't need to worry about whether or all our weapons have the same variables.
           variables to the knife, we don't need to worry about whether or all our weapons have the same variables.
 
 
 Add the following class variables to ``Weapon_Rifle.gd``:
 Add the following class variables to ``Weapon_Rifle.gd``:
 
 
 ::
 ::
-    
+
     var ammo_in_weapon = 50
     var ammo_in_weapon = 50
     var spare_ammo = 100
     var spare_ammo = 100
     const AMMO_IN_MAG = 50
     const AMMO_IN_MAG = 50
@@ -122,7 +122,7 @@ the player loses ammo regardless of whether the player hit something or not.
 Now all that's left is the knife. Add the following to ``Weapon_Knife.gd``:
 Now all that's left is the knife. Add the following to ``Weapon_Knife.gd``:
 
 
 ::
 ::
-    
+
     var ammo_in_weapon = 1
     var ammo_in_weapon = 1
     var spare_ammo = 1
     var spare_ammo = 1
     const AMMO_IN_MAG = 1
     const AMMO_IN_MAG = 1
@@ -136,7 +136,7 @@ Now all we need to do is change a one thing in ``Player.gd``.
 All we need to change how we're firing the weapons in ``process_input``. Change the code for firing weapons to the following:
 All we need to change how we're firing the weapons in ``process_input``. Change the code for firing weapons to the following:
 
 
 ::
 ::
-    
+
     # ----------------------------------
     # ----------------------------------
     # Firing the weapons
     # Firing the weapons
     if Input.is_action_pressed("fire"):
     if Input.is_action_pressed("fire"):
@@ -147,7 +147,7 @@ All we need to change how we're firing the weapons in ``process_input``. Change
                     if animation_manager.current_state == current_weapon.IDLE_ANIM_NAME:
                     if animation_manager.current_state == current_weapon.IDLE_ANIM_NAME:
                         animation_manager.set_animation(current_weapon.FIRE_ANIM_NAME)
                         animation_manager.set_animation(current_weapon.FIRE_ANIM_NAME)
     # ----------------------------------
     # ----------------------------------
-    
+
 Now the weapons have a limited amount of ammo, and will stop firing when the player runs out.
 Now the weapons have a limited amount of ammo, and will stop firing when the player runs out.
 
 
 _______
 _______
@@ -159,7 +159,7 @@ First, add ``process_UI(delta)`` to ``_physics_process``.
 Now add the following to ``Player.gd``:
 Now add the following to ``Player.gd``:
 
 
 ::
 ::
-    
+
     func process_UI(delta):
     func process_UI(delta):
         if current_weapon_name == "UNARMED" or current_weapon_name == "KNIFE":
         if current_weapon_name == "UNARMED" or current_weapon_name == "KNIFE":
             UI_status_label.text = "HEALTH: " + str(health)
             UI_status_label.text = "HEALTH: " + str(health)
@@ -191,10 +191,10 @@ For reloading we need to add a few more variables and a function to every weapon
 Open up ``Weapon_Pistol.gd`` and add the following class variables:
 Open up ``Weapon_Pistol.gd`` and add the following class variables:
 
 
 ::
 ::
-    
+
     const CAN_RELOAD = true
     const CAN_RELOAD = true
     const CAN_REFILL = true
     const CAN_REFILL = true
-    
+
     const RELOADING_ANIM_NAME = "Pistol_reload"
     const RELOADING_ANIM_NAME = "Pistol_reload"
 
 
 * ``CAN_RELOAD``: A boolean to track whether this weapon has the ability to reload
 * ``CAN_RELOAD``: A boolean to track whether this weapon has the ability to reload
@@ -204,32 +204,32 @@ Open up ``Weapon_Pistol.gd`` and add the following class variables:
 Now we need to add a function for handling reloading. Add the following function to ``Weapon_Pistol.gd``:
 Now we need to add a function for handling reloading. Add the following function to ``Weapon_Pistol.gd``:
 
 
 ::
 ::
-    
+
     func reload_weapon():
     func reload_weapon():
         var can_reload = false
         var can_reload = false
-        
+
         if player_node.animation_manager.current_state == IDLE_ANIM_NAME:
         if player_node.animation_manager.current_state == IDLE_ANIM_NAME:
             can_reload = true
             can_reload = true
-        
+
         if spare_ammo <= 0 or ammo_in_weapon == AMMO_IN_MAG:
         if spare_ammo <= 0 or ammo_in_weapon == AMMO_IN_MAG:
             can_reload = false
             can_reload = false
-        
+
         if can_reload == true:
         if can_reload == true:
             var ammo_needed = AMMO_IN_MAG - ammo_in_weapon
             var ammo_needed = AMMO_IN_MAG - ammo_in_weapon
-            
+
             if spare_ammo >= ammo_needed:
             if spare_ammo >= ammo_needed:
                 spare_ammo -= ammo_needed
                 spare_ammo -= ammo_needed
                 ammo_in_weapon = AMMO_IN_MAG
                 ammo_in_weapon = AMMO_IN_MAG
             else:
             else:
                 ammo_in_weapon += spare_ammo
                 ammo_in_weapon += spare_ammo
                 spare_ammo = 0
                 spare_ammo = 0
-            
+
             player_node.animation_manager.set_animation(RELOADING_ANIM_NAME)
             player_node.animation_manager.set_animation(RELOADING_ANIM_NAME)
-            
+
             return true
             return true
-        
+
         return false
         return false
-    
+
 Let's go over what's happening:
 Let's go over what's happening:
 
 
 First we define a variable to see whether or not this weapon can reload.
 First we define a variable to see whether or not this weapon can reload.
@@ -255,41 +255,41 @@ _______
 Now we need to add reloading to the rifle. Open up ``Weapon_Rifle.gd`` and add the following class variables:
 Now we need to add reloading to the rifle. Open up ``Weapon_Rifle.gd`` and add the following class variables:
 
 
 ::
 ::
-    
+
     const CAN_RELOAD = true
     const CAN_RELOAD = true
     const CAN_REFILL = true
     const CAN_REFILL = true
-    
+
     const RELOADING_ANIM_NAME = "Rifle_reload"
     const RELOADING_ANIM_NAME = "Rifle_reload"
-    
+
 These variables are exactly the same as the pistol, just with ``RELOADING_ANIM_NAME`` changed to the rifle's reloading animation.
 These variables are exactly the same as the pistol, just with ``RELOADING_ANIM_NAME`` changed to the rifle's reloading animation.
 
 
 Now we need to add ``reload_weapon`` to ``Weapon_Rifle.gd``:
 Now we need to add ``reload_weapon`` to ``Weapon_Rifle.gd``:
 
 
 ::
 ::
-    
+
     func reload_weapon():
     func reload_weapon():
         var can_reload = false
         var can_reload = false
-        
+
         if player_node.animation_manager.current_state == IDLE_ANIM_NAME:
         if player_node.animation_manager.current_state == IDLE_ANIM_NAME:
             can_reload = true
             can_reload = true
-        
+
         if spare_ammo <= 0 or ammo_in_weapon == AMMO_IN_MAG:
         if spare_ammo <= 0 or ammo_in_weapon == AMMO_IN_MAG:
             can_reload = false
             can_reload = false
-        
+
         if can_reload == true:
         if can_reload == true:
             var ammo_needed = AMMO_IN_MAG - ammo_in_weapon
             var ammo_needed = AMMO_IN_MAG - ammo_in_weapon
-            
+
             if spare_ammo >= ammo_needed:
             if spare_ammo >= ammo_needed:
                 spare_ammo -= ammo_needed
                 spare_ammo -= ammo_needed
                 ammo_in_weapon = AMMO_IN_MAG
                 ammo_in_weapon = AMMO_IN_MAG
             else:
             else:
                 ammo_in_weapon += spare_ammo
                 ammo_in_weapon += spare_ammo
                 spare_ammo = 0
                 spare_ammo = 0
-            
+
             player_node.animation_manager.set_animation(RELOADING_ANIM_NAME)
             player_node.animation_manager.set_animation(RELOADING_ANIM_NAME)
-            
+
             return true
             return true
-        
+
         return false
         return false
 
 
 This code is exactly the same as the pistol.
 This code is exactly the same as the pistol.
@@ -299,7 +299,7 @@ _______
 The last bit we need to do for the weapons is add 'reloading' to the knife. Add the following class variables to ``Weapon_Knife.gd``:
 The last bit we need to do for the weapons is add 'reloading' to the knife. Add the following class variables to ``Weapon_Knife.gd``:
 
 
 ::
 ::
-    
+
     const CAN_RELOAD = false
     const CAN_RELOAD = false
     const CAN_REFILL = false
     const CAN_REFILL = false
 
 
@@ -311,7 +311,7 @@ has no reloading animation.
 Now we need to add ``reloading_weapon``:
 Now we need to add ``reloading_weapon``:
 
 
 ::
 ::
-    
+
     func reload_weapon():
     func reload_weapon():
         return false
         return false
 
 
@@ -323,9 +323,9 @@ Adding reloading to the player
 Now we need to add a few things to ``Player.gd``. First we need to define a new class variable:
 Now we need to add a few things to ``Player.gd``. First we need to define a new class variable:
 
 
 ::
 ::
-    
+
     var reloading_weapon = false
     var reloading_weapon = false
-    
+
 * ``reloading_weapon``: A variable to track whether or not the player is currently trying to reload.
 * ``reloading_weapon``: A variable to track whether or not the player is currently trying to reload.
 
 
 
 
@@ -334,7 +334,7 @@ Next we need to add another function call to ``_physics_process``.
 Add ``process_reloading(delta)`` to ``_physics_process``. Now ``_physics_process`` should look something like this:
 Add ``process_reloading(delta)`` to ``_physics_process``. Now ``_physics_process`` should look something like this:
 
 
 ::
 ::
-    
+
     func _physics_process(delta):
     func _physics_process(delta):
         process_input(delta)
         process_input(delta)
         process_movement(delta)
         process_movement(delta)
@@ -345,7 +345,7 @@ Add ``process_reloading(delta)`` to ``_physics_process``. Now ``_physics_process
 Now we need to add ``process_reloading``. Add the following function to ``Player.gd``:
 Now we need to add ``process_reloading``. Add the following function to ``Player.gd``:
 
 
 ::
 ::
-    
+
     func process_reloading(delta):
     func process_reloading(delta):
         if reloading_weapon == true:
         if reloading_weapon == true:
             var current_weapon = weapons[current_weapon_name]
             var current_weapon = weapons[current_weapon_name]
@@ -371,7 +371,7 @@ Before we can let the player reload, we need to change a few things in ``process
 The first thing we need to change is in the code for changing weapons. We need to add a additional check (``if reloading_weapon == false:``) to see if the player is reloading:
 The first thing we need to change is in the code for changing weapons. We need to add a additional check (``if reloading_weapon == false:``) to see if the player is reloading:
 
 
 ::
 ::
-    
+
     if changing_weapon == false:
     if changing_weapon == false:
         # New line of code here!
         # New line of code here!
         if reloading_weapon == false:
         if reloading_weapon == false:
@@ -384,7 +384,7 @@ This makes it so the player cannot change weapons if the player is reloading.
 Now we need to add the code to trigger a reload when the player pushes the ``reload`` action. Add the following code to ``process_input``:
 Now we need to add the code to trigger a reload when the player pushes the ``reload`` action. Add the following code to ``process_input``:
 
 
 ::
 ::
-    
+
     # ----------------------------------
     # ----------------------------------
     # Reloading
     # Reloading
     if reloading_weapon == false:
     if reloading_weapon == false:
@@ -429,7 +429,7 @@ reloading.
 Let's change our firing code in ``process_input`` so it reloads when trying to fire an empty weapon:
 Let's change our firing code in ``process_input`` so it reloads when trying to fire an empty weapon:
 
 
 ::
 ::
-    
+
     # ----------------------------------
     # ----------------------------------
     # Firing the weapons
     # Firing the weapons
     if Input.is_action_pressed("fire"):
     if Input.is_action_pressed("fire"):
@@ -448,11 +448,11 @@ Now we check to make sure the player is not reloading before we fire the weapon,
 we set ``reloading_weapon`` to ``true`` if the player tries to fire.
 we set ``reloading_weapon`` to ``true`` if the player tries to fire.
 
 
 This will make it where the player will try to reload when the player tries to fire a empty weapon.
 This will make it where the player will try to reload when the player tries to fire a empty weapon.
-    
+
 _______
 _______
-    
+
 With that done, the player can now reload! Give it a try! Now you can fire all of the spare ammo for each weapon.
 With that done, the player can now reload! Give it a try! Now you can fire all of the spare ammo for each weapon.
-    
+
 Adding sounds
 Adding sounds
 -------------
 -------------
 
 
@@ -497,12 +497,12 @@ and insert the following code:
 
 
 
 
     func play_sound(sound_name, position=null):
     func play_sound(sound_name, position=null):
-    
+
         if audio_pistol_shot == null or audio_rifle_shot == null or audio_gun_cock == null:
         if audio_pistol_shot == null or audio_rifle_shot == null or audio_gun_cock == null:
             print ("Audio not set!")
             print ("Audio not set!")
             queue_free()
             queue_free()
             return
             return
-    
+
         if sound_name == "Pistol_shot":
         if sound_name == "Pistol_shot":
             audio_node.stream = audio_pistol_shot
             audio_node.stream = audio_pistol_shot
         elif sound_name == "Rifle_shot":
         elif sound_name == "Rifle_shot":
@@ -566,7 +566,7 @@ to save on resources.
           Because we cannot play looping sounds, certain effects, like footstep sounds, are harder to accomplish
           Because we cannot play looping sounds, certain effects, like footstep sounds, are harder to accomplish
           because we then have to keep track of whether or not there is a sound effect and whether or not we
           because we then have to keep track of whether or not there is a sound effect and whether or not we
           need to continue playing it.
           need to continue playing it.
-          
+
           One of the biggest flaws with this system is we can only play sounds from ``Player.gd``.
           One of the biggest flaws with this system is we can only play sounds from ``Player.gd``.
           Ideally we'd like to be able to play sounds from any script at any time.
           Ideally we'd like to be able to play sounds from any script at any time.
 
 
@@ -625,7 +625,7 @@ Open up ``Weapon_Pistol.gd``.
 Now, we want to make a noise when the player fires the pistol, so add the following to the end of the ``fire_weapon`` function:
 Now, we want to make a noise when the player fires the pistol, so add the following to the end of the ``fire_weapon`` function:
 
 
 ::
 ::
-    
+
     player_node.create_sound("Pistol_shot", self.global_transform.origin)
     player_node.create_sound("Pistol_shot", self.global_transform.origin)
 
 
 Now when the player fires the pistol, we'll play the ``Pistol_shot`` sound.
 Now when the player fires the pistol, we'll play the ``Pistol_shot`` sound.
@@ -634,7 +634,7 @@ To make a sound when the player reloads, we need to add the following right unde
 ``reload_weapon`` function:
 ``reload_weapon`` function:
 
 
 ::
 ::
-    
+
     player_node.create_sound("Gun_cock", player_node.camera.global_transform.origin)
     player_node.create_sound("Gun_cock", player_node.camera.global_transform.origin)
 
 
 Now when the player reloads, we'll play the ``Gun_cock`` sound.
 Now when the player reloads, we'll play the ``Gun_cock`` sound.
@@ -647,7 +647,7 @@ Open up ``Weapon_Rifle.gd``.
 To play sounds when the rifle is fired, add the following to the end of the ``fire_weapon`` function:
 To play sounds when the rifle is fired, add the following to the end of the ``fire_weapon`` function:
 
 
 ::
 ::
-    
+
     player_node.create_sound("Rifle_shot", ray.global_transform.origin)
     player_node.create_sound("Rifle_shot", ray.global_transform.origin)
 
 
 Now when the player fires the rifle, we'll play the ``Rifle_shot`` sound.
 Now when the player fires the rifle, we'll play the ``Rifle_shot`` sound.
@@ -656,7 +656,7 @@ To make a sound when the player reloads, we need to add the following right unde
 ``reload_weapon`` function:
 ``reload_weapon`` function:
 
 
 ::
 ::
-    
+
     player_node.create_sound("Gun_cock", player_node.camera.global_transform.origin)
     player_node.create_sound("Gun_cock", player_node.camera.global_transform.origin)
 
 
 Now when the player reloads, we'll play the ``Gun_cock`` sound.
 Now when the player reloads, we'll play the ``Gun_cock`` sound.

+ 1 - 1
tutorials/3d/fps_tutorial/part_two.rst

@@ -1205,7 +1205,7 @@ Now we need to add this code:
 
 
     func bullet_hit(damage, bullet_global_trans):
     func bullet_hit(damage, bullet_global_trans):
         var direction_vect = bullet_global_trans.basis.z.normalized() * BASE_BULLET_BOOST;
         var direction_vect = bullet_global_trans.basis.z.normalized() * BASE_BULLET_BOOST;
-        
+
         apply_impulse((bullet_global_trans.origin - global_transform.origin).normalized(), direction_vect * damage)
         apply_impulse((bullet_global_trans.origin - global_transform.origin).normalized(), direction_vect * damage)
 
 
 
 

+ 1 - 1
tutorials/3d/introduction_to_3d.rst

@@ -173,7 +173,7 @@ You can hide the gizmos in the 3D view of the editor through this menu:
 .. image:: img/tuto_3d6_1.png
 .. image:: img/tuto_3d6_1.png
 
 
 To hide a specific type of gizmos, you can toggle them off in the "View" menu.
 To hide a specific type of gizmos, you can toggle them off in the "View" menu.
- 
+
 .. image:: img/tuto_3d6_2.png
 .. image:: img/tuto_3d6_2.png
 
 
 Default environment
 Default environment

+ 3 - 3
tutorials/3d/using_gridmaps.rst

@@ -8,7 +8,7 @@ Introduction
 
 
 :ref:`Gridmaps <class_GridMap>` are a tool for creating 3D
 :ref:`Gridmaps <class_GridMap>` are a tool for creating 3D
 game levels, similar to the way :ref:`TileMap <doc_using_tilemaps>`
 game levels, similar to the way :ref:`TileMap <doc_using_tilemaps>`
-works in 2D. You start with a predefined collection of 3D meshes (a 
+works in 2D. You start with a predefined collection of 3D meshes (a
 :ref:`class_MeshLibrary`) that can be placed on a grid,
 :ref:`class_MeshLibrary`) that can be placed on a grid,
 as if you were building a level with an unlimited amount of Lego blocks.
 as if you were building a level with an unlimited amount of Lego blocks.
 
 
@@ -34,7 +34,7 @@ scene to see an example of how to set up the mesh library.
 .. image:: img/gridmap_meshlibrary1.png
 .. image:: img/gridmap_meshlibrary1.png
 
 
 As you can see, this scene has a :ref:`class_Spatial` node as its root, and
 As you can see, this scene has a :ref:`class_Spatial` node as its root, and
-a number of :ref:`class_MeshInstance` node children. 
+a number of :ref:`class_MeshInstance` node children.
 
 
 If you don't need any physics in your scene, then you're done. However, in most
 If you don't need any physics in your scene, then you're done. However, in most
 cases you'll want to assign collision bodies to the meshes.
 cases you'll want to assign collision bodies to the meshes.
@@ -42,7 +42,7 @@ cases you'll want to assign collision bodies to the meshes.
 Collisions
 Collisions
 ----------
 ----------
 
 
-You can manually assign a :ref:`class_StaticBody` and 
+You can manually assign a :ref:`class_StaticBody` and
 :ref:`class_CollisionShape` to each mesh. Alternatively, you can use the "Mesh" menu
 :ref:`class_CollisionShape` to each mesh. Alternatively, you can use the "Mesh" menu
 to automatically create the collision body based on the mesh data.
 to automatically create the collision body based on the mesh data.
 
 

+ 3 - 3
tutorials/3d/using_transforms.rst

@@ -116,7 +116,7 @@ A default basis (unmodified) is akin to:
     GD.Print(identityBasis.y); // prints: (0, 1, 0)
     GD.Print(identityBasis.y); // prints: (0, 1, 0)
     GD.Print(identityBasis.z); // prints: (0, 0, 1)
     GD.Print(identityBasis.z); // prints: (0, 0, 1)
 
 
-    // The Identity basis is equivalent to: 
+    // The Identity basis is equivalent to:
     var basis = new Basis(Vector3.Right, Vector3.Up, Vector3.Back);
     var basis = new Basis(Vector3.Right, Vector3.Up, Vector3.Back);
     GD.Print(basis); // prints: ((1, 0, 0), (0, 1, 0), (0, 0, 1))
     GD.Print(basis); // prints: ((1, 0, 0), (0, 1, 0), (0, 0, 1))
 
 
@@ -189,7 +189,7 @@ To rotate relative to object space (the node's own transform) use the following:
     rotate_object_local(Vector3(1, 0, 0), PI)
     rotate_object_local(Vector3(1, 0, 0), PI)
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
-    
+
     // Rotate locally
     // Rotate locally
     RotateObjectLocal(Vector3.Right, Mathf.Pi);
     RotateObjectLocal(Vector3.Right, Mathf.Pi);
 
 
@@ -341,7 +341,7 @@ Example of looking around, FPS style:
             // modify accumulated mouse rotation
             // modify accumulated mouse rotation
             _rotationX += mouseMotion.Relative.x * LookAroundSpeed;
             _rotationX += mouseMotion.Relative.x * LookAroundSpeed;
             _rotationY += mouseMotion.Relative.y * LookAroundSpeed;
             _rotationY += mouseMotion.Relative.y * LookAroundSpeed;
-            
+
             // reset rotation
             // reset rotation
             Transform transform = Transform;
             Transform transform = Transform;
             transform.basis = Basis.Identity;
             transform.basis = Basis.Identity;

+ 32 - 32
tutorials/3d/vertex_displacement_with_shaders.rst

@@ -6,13 +6,13 @@ Vertex displacement with shaders
 Introduction
 Introduction
 ------------
 ------------
 
 
-This tutorial will teach you how to displace the vertices of 
-a :ref:`Plane Mesh<class_PlaneMesh>` inside a shader. Vertex displacement can be used 
+This tutorial will teach you how to displace the vertices of
+a :ref:`Plane Mesh<class_PlaneMesh>` inside a shader. Vertex displacement can be used
 for a wide variety of effects, but most commonly it is used
 for a wide variety of effects, but most commonly it is used
 as a quick way to turn a flat plane into a simple terrain. Typically
 as a quick way to turn a flat plane into a simple terrain. Typically
 this is done using a heightmap, but in order to keep everything self
 this is done using a heightmap, but in order to keep everything self
 contained, in this tutorial we will use noise in a shader. At the end
 contained, in this tutorial we will use noise in a shader. At the end
-of this tutorial we will have a deformed plane that looks like a 
+of this tutorial we will have a deformed plane that looks like a
 miniature terrain complete with dynamic lighting.
 miniature terrain complete with dynamic lighting.
 
 
 By reading this tutorial you should gain a basic understanding of:
 By reading this tutorial you should gain a basic understanding of:
@@ -28,18 +28,18 @@ The plane mesh
 --------------
 --------------
 
 
 First, add a :ref:`Spatial<class_Spatial>` node to the scene to act as the root. Next, add a :ref:`MeshInstance<class_MeshInstance>`
 First, add a :ref:`Spatial<class_Spatial>` node to the scene to act as the root. Next, add a :ref:`MeshInstance<class_MeshInstance>`
-as a child. 
+as a child.
 
 
 .. image:: img/vertex_displacement_new_mesh.png
 .. image:: img/vertex_displacement_new_mesh.png
 
 
-Select the newly created :ref:`MeshInstance<class_MeshInstance>`. Then click on the button that says "null" 
+Select the newly created :ref:`MeshInstance<class_MeshInstance>`. Then click on the button that says "null"
 next to the :ref:`Mesh<class_MeshInstance>` in the Inspector. This will bring up a list of :ref:`PrimitiveMeshes<class_PrimitiveMesh>`.
 next to the :ref:`Mesh<class_MeshInstance>` in the Inspector. This will bring up a list of :ref:`PrimitiveMeshes<class_PrimitiveMesh>`.
 Select "New PlaneMesh".
 Select "New PlaneMesh".
 
 
 .. image:: img/vertex_displacement_planemesh.png
 .. image:: img/vertex_displacement_planemesh.png
 
 
 The button will change into a small image of a plane. Click on it to enter into
 The button will change into a small image of a plane. Click on it to enter into
-the Inspector for the :ref:`Plane Mesh<class_MeshInstance>`. 
+the Inspector for the :ref:`Plane Mesh<class_MeshInstance>`.
 
 
 Then, in the viewport, click in the upper left corner where it says [Perspective].
 Then, in the viewport, click in the upper left corner where it says [Perspective].
 A menu will appear. In the middle of the menu are options for how to display the scene.
 A menu will appear. In the middle of the menu are options for how to display the scene.
@@ -96,7 +96,7 @@ the ``render_mode`` the plane would appear blue because it would pick up the sky
 
 
 Next we will define a vertex shader. The vertex shader determines where the vertices of your
 Next we will define a vertex shader. The vertex shader determines where the vertices of your
 :ref:`Mesh<class_MeshInstance>` appear in the final scene. We will be using it to offset the height of each vertex and
 :ref:`Mesh<class_MeshInstance>` appear in the final scene. We will be using it to offset the height of each vertex and
-make our flat plane appear like a little terrain. 
+make our flat plane appear like a little terrain.
 
 
 We define the vertex shader like so:
 We define the vertex shader like so:
 
 
@@ -106,7 +106,7 @@ We define the vertex shader like so:
 
 
   }
   }
 
 
-With nothing in the ``vertex`` function Godot will use its default vertex shader. We can easily 
+With nothing in the ``vertex`` function Godot will use its default vertex shader. We can easily
 start to make changes by adding a single line:
 start to make changes by adding a single line:
 
 
 ::
 ::
@@ -114,14 +114,14 @@ start to make changes by adding a single line:
   void vertex() {
   void vertex() {
     VERTEX.y += cos(VERTEX.x) * sin(VERTEX.z);
     VERTEX.y += cos(VERTEX.x) * sin(VERTEX.z);
   }
   }
-  
+
 Adding this line you should get an image like the one below.
 Adding this line you should get an image like the one below.
 
 
 .. image:: img/vertex_displacement_cos.png
 .. image:: img/vertex_displacement_cos.png
 
 
 Okay, lets unpack this. The ``y`` value of the ``VERTEX`` is being increased. And we are passing
 Okay, lets unpack this. The ``y`` value of the ``VERTEX`` is being increased. And we are passing
 the ``x`` and ``z`` components of the ``VERTEX`` as arguments to ``cos`` and ``sin`` this gives us
 the ``x`` and ``z`` components of the ``VERTEX`` as arguments to ``cos`` and ``sin`` this gives us
-a wave like appearance across the ``x`` and ``z`` axis. 
+a wave like appearance across the ``x`` and ``z`` axis.
 
 
 What we want to achieve is the look of little hills, after all ``cos`` and ``sin`` already look kind of like
 What we want to achieve is the look of little hills, after all ``cos`` and ``sin`` already look kind of like
 hills. We do so by scaling the inputs to the ``cos`` and ``sin`` functions.
 hills. We do so by scaling the inputs to the ``cos`` and ``sin`` functions.
@@ -134,7 +134,7 @@ hills. We do so by scaling the inputs to the ``cos`` and ``sin`` functions.
 
 
 .. image:: img/vertex_displacement_cos_scaled.png
 .. image:: img/vertex_displacement_cos_scaled.png
 
 
-This looks better, but it is still too spiky. This is because ``cos`` and ``sin`` output values between ``-1`` and ``1``, 
+This looks better, but it is still too spiky. This is because ``cos`` and ``sin`` output values between ``-1`` and ``1``,
 so the range of the output is much too high. We correct this by multiplying the result by ``0.5`` to reduce the size.
 so the range of the output is much too high. We correct this by multiplying the result by ``0.5`` to reduce the size.
 
 
 ::
 ::
@@ -151,12 +151,12 @@ Noise
 -----
 -----
 
 
 Noise is a very popular tool for procedural generation. Think of it as similar to the cosine function
 Noise is a very popular tool for procedural generation. Think of it as similar to the cosine function
-where you have repeating hills except with noise each hill has a different height. Understanding 
+where you have repeating hills except with noise each hill has a different height. Understanding
 noise is not necessary for this tutorial. There is nothing wrong with simply copying and pasting
 noise is not necessary for this tutorial. There is nothing wrong with simply copying and pasting
 the code below.
 the code below.
 
 
 The first function we use to generate the noise is the ``hash`` function. It gives the random height
 The first function we use to generate the noise is the ``hash`` function. It gives the random height
-for each of the hill tops. 
+for each of the hill tops.
 
 
 ::
 ::
 
 
@@ -165,8 +165,8 @@ for each of the hill tops.
   }
   }
 
 
 You will find similar functions to this all over the internet. It is lovingly referred to as the
 You will find similar functions to this all over the internet. It is lovingly referred to as the
-'one-liner hash function'. It works well for simple noise, but there are many better alternatives 
-floating around as well. For this tutorial it will work fine. 
+'one-liner hash function'. It works well for simple noise, but there are many better alternatives
+floating around as well. For this tutorial it will work fine.
 
 
 Next we define the ``noise`` function. It smoothly interpolates between the random heights.
 Next we define the ``noise`` function. It smoothly interpolates between the random heights.
 Again, if this code seems daunting, do not worry, just copy paste and move on with the tutorial.
 Again, if this code seems daunting, do not worry, just copy paste and move on with the tutorial.
@@ -178,7 +178,7 @@ Again, if this code seems daunting, do not worry, just copy paste and move on wi
     vec2 f = fract(x);
     vec2 f = fract(x);
     f = f * f * (3.0 - 2.0 * f);
     f = f * f * (3.0 - 2.0 * f);
     vec2 a = vec2(1.0, 0.0);
     vec2 a = vec2(1.0, 0.0);
-    return mix(mix(hash(p + a.yy), hash(p + a.xy), f.x), 
+    return mix(mix(hash(p + a.yy), hash(p + a.xy), f.x),
            mix(hash(p + a.yx), hash(p + a.xx), f.x), f.y);
            mix(hash(p + a.yx), hash(p + a.xx), f.x), f.y);
   }
   }
 
 
@@ -201,7 +201,7 @@ we increase the frequency each level, decrease the amplitude, and calculate a ne
     return height;
     return height;
   }
   }
 
 
-We can now use this noise function in place of ``cos`` and ``sin`` in the previous section. 
+We can now use this noise function in place of ``cos`` and ``sin`` in the previous section.
 
 
 ::
 ::
 
 
@@ -211,7 +211,7 @@ We can now use this noise function in place of ``cos`` and ``sin`` in the previo
 .. image:: img/vertex_displacement_noise1.png
 .. image:: img/vertex_displacement_noise1.png
 
 
 With the noise function in place we already have something that looks kind of cool.
 With the noise function in place we already have something that looks kind of cool.
-There is a lot of detail, it kind of looks hilly or mountainous. 
+There is a lot of detail, it kind of looks hilly or mountainous.
 
 
 Fragment shader
 Fragment shader
 ---------------
 ---------------
@@ -220,14 +220,14 @@ The difference between a vertex shader and a fragment shader is that the vertex
 runs per vertex and sets properties such as ``VERTEX`` (position) and ``NORMAL``, while
 runs per vertex and sets properties such as ``VERTEX`` (position) and ``NORMAL``, while
 the fragment shader runs per pixel and, most importantly, sets the ``ALBEDO`` color of the :ref:`Mesh<class_MeshInstance>`.
 the fragment shader runs per pixel and, most importantly, sets the ``ALBEDO`` color of the :ref:`Mesh<class_MeshInstance>`.
 
 
-Now lets look at the :ref:`Mesh<class_MeshInstance>` with a regular shader instead of the wireframe. Set the 
+Now lets look at the :ref:`Mesh<class_MeshInstance>` with a regular shader instead of the wireframe. Set the
 viewport back to 'Display Normal'.
 viewport back to 'Display Normal'.
 
 
 .. image:: img/vertex_displacement_noise2.png
 .. image:: img/vertex_displacement_noise2.png
 
 
 The :ref:`Mesh<class_MeshInstance>` appears completely white because the fragment shader is coloring each pixel white,
 The :ref:`Mesh<class_MeshInstance>` appears completely white because the fragment shader is coloring each pixel white,
 but if every pixel is white we lose detail on the :ref:`Mesh<class_MeshInstance>`. So lets color each pixel based
 but if every pixel is white we lose detail on the :ref:`Mesh<class_MeshInstance>`. So lets color each pixel based
-on the height calculated in the vertex shader. We do so by setting the ``COLOR`` variable 
+on the height calculated in the vertex shader. We do so by setting the ``COLOR`` variable
 in the vertex shader. And by setting the ``ALBEDO`` in the fragment shader to the calculated
 in the vertex shader. And by setting the ``ALBEDO`` in the fragment shader to the calculated
 ``COLOR`` variable.
 ``COLOR`` variable.
 
 
@@ -250,7 +250,7 @@ Uniforms
 --------
 --------
 
 
 Uniform variables allow you to pass data from the game into the shader. They can
 Uniform variables allow you to pass data from the game into the shader. They can
-be very useful for controlling shader effects. Uniforms can be almost any 
+be very useful for controlling shader effects. Uniforms can be almost any
 datatype that can be used in the shader. To use a uniform you declare it in
 datatype that can be used in the shader. To use a uniform you declare it in
 your :ref:`Shader<class_Shader>` using the keyword ``uniform``.
 your :ref:`Shader<class_Shader>` using the keyword ``uniform``.
 
 
@@ -262,16 +262,16 @@ Lets make a uniform that changes the height of the terrain.
 
 
 
 
 Godot lets you initialize a uniform with a value, here ``height_scale`` is set to
 Godot lets you initialize a uniform with a value, here ``height_scale`` is set to
-``0.5``. You can set uniforms from gdscript by calling the function ``set_shader_param`` 
+``0.5``. You can set uniforms from gdscript by calling the function ``set_shader_param``
 on the material corresponding to the shader. The value passed from gdscript takes
 on the material corresponding to the shader. The value passed from gdscript takes
 precedence over the value used to initialize it in the shader.
 precedence over the value used to initialize it in the shader.
 
 
-:: 
+::
 
 
   material.set_shader_param("height_scale", 0.5)
   material.set_shader_param("height_scale", 0.5)
 
 
 Remember that the string passed into ``set_shader_param`` must match the name
 Remember that the string passed into ``set_shader_param`` must match the name
-of the uniform variable in the :ref:`Shader<class_Shader>`. You can use the uniform variable anywhere 
+of the uniform variable in the :ref:`Shader<class_Shader>`. You can use the uniform variable anywhere
 inside your :ref:`Shader<class_Shader>`. Here, we will use it to set the height value instead
 inside your :ref:`Shader<class_Shader>`. Here, we will use it to set the height value instead
 of arbitrarily multiplying by ``0.5``.
 of arbitrarily multiplying by ``0.5``.
 
 
@@ -313,15 +313,15 @@ at the beginning of this tutorial, lets remove that.
 It looks slightly better now, you can see the light affecting the terrain, and it has
 It looks slightly better now, you can see the light affecting the terrain, and it has
 turned blue as a result of the sky. The problem is the light is affecting the terrain
 turned blue as a result of the sky. The problem is the light is affecting the terrain
 as if it were a flat plane. This is because the light shader uses the normals of the
 as if it were a flat plane. This is because the light shader uses the normals of the
-:ref:`Mesh<class_MeshInstance>` to calculate light. The normals are stored in the :ref:`Mesh<class_MeshInstance>`, but we are changing 
+:ref:`Mesh<class_MeshInstance>` to calculate light. The normals are stored in the :ref:`Mesh<class_MeshInstance>`, but we are changing
 the shape of the :ref:`Mesh<class_MeshInstance>` in the shader so the normals are no longer correct. To fix this
 the shape of the :ref:`Mesh<class_MeshInstance>` in the shader so the normals are no longer correct. To fix this
 we need to recalculate the normals in the shader. Godot makes this easy for us, all we
 we need to recalculate the normals in the shader. Godot makes this easy for us, all we
 have to do is calculate the new normal and set ``NORMAL`` to that value in the vertex shader.
 have to do is calculate the new normal and set ``NORMAL`` to that value in the vertex shader.
 With ``NORMAL`` set Godot will do all the difficult lighting calculations for us.
 With ``NORMAL`` set Godot will do all the difficult lighting calculations for us.
 
 
 To calculate the normal from noise we are going to use a technique called 'central differences'.
 To calculate the normal from noise we are going to use a technique called 'central differences'.
-This is used a lot, especially in places like shadertoy, to calculate normals in shaders. 
-What we will do is calculate the noise at four points surrounding the vertex in the ``x`` and ``z`` directions and then calculate 
+This is used a lot, especially in places like shadertoy, to calculate normals in shaders.
+What we will do is calculate the noise at four points surrounding the vertex in the ``x`` and ``z`` directions and then calculate
 the slope at the vertex from that. After all a normal is just an indicator of the slope of the
 the slope at the vertex from that. After all a normal is just an indicator of the slope of the
 noise.
 noise.
 
 
@@ -333,15 +333,15 @@ We calculate the normal with one line in the vertex shader.
   vec3 normal = normalize(vec3(fbm(VERTEX.xz - e) - fbm(VERTEX.xz + e), 2.0 * e.x, fbm(VERTEX.xz - e.yx) - fbm(VERTEX.xz + e.yx)));
   vec3 normal = normalize(vec3(fbm(VERTEX.xz - e) - fbm(VERTEX.xz + e), 2.0 * e.x, fbm(VERTEX.xz - e.yx) - fbm(VERTEX.xz + e.yx)));
   NORMAL = normal;
   NORMAL = normal;
 
 
-The variable ``e`` just makes it easier to add and subtract the right value from the ``VERTEX``. 
-Setting ``e`` to a lower number will increase the level of detail of the normal. 
+The variable ``e`` just makes it easier to add and subtract the right value from the ``VERTEX``.
+Setting ``e`` to a lower number will increase the level of detail of the normal.
 
 
 With ``NORMAL`` calculated the terrain now looks like:
 With ``NORMAL`` calculated the terrain now looks like:
 
 
 .. image:: img/vertex_displacement_normal.png
 .. image:: img/vertex_displacement_normal.png
 
 
-This still does not look how we want it to. The issue here is that the noise changes 
-faster than the vertices do. So when we calculate the normal at the point of the 
+This still does not look how we want it to. The issue here is that the noise changes
+faster than the vertices do. So when we calculate the normal at the point of the
 ``VERTEX`` it does not align with what we see in the final :ref:`Mesh<class_MeshInstance>`. In order to fix
 ``VERTEX`` it does not align with what we see in the final :ref:`Mesh<class_MeshInstance>`. In order to fix
 this we add more vertices. The below image is made with a :ref:`Mesh<class_MeshInstance>` with ``subdivision`` set
 this we add more vertices. The below image is made with a :ref:`Mesh<class_MeshInstance>` with ``subdivision`` set
 to ``100``.
 to ``100``.
@@ -363,6 +363,6 @@ shaders in Godot. As a further exercise try changing the ``height_scale`` from g
 try using different :ref:`Primitive Meshes<class_PrimitiveMesh>`, and try making your
 try using different :ref:`Primitive Meshes<class_PrimitiveMesh>`, and try making your
 own functions to calculate ``height``.
 own functions to calculate ``height``.
 
 
-For further information on how to use shaders in Godot 
+For further information on how to use shaders in Godot
 you should check out the :ref:`doc_shading_language` page.
 you should check out the :ref:`doc_shading_language` page.
 
 

+ 7 - 7
tutorials/animation/cutout_animation.rst

@@ -81,7 +81,7 @@ create a child sprite and load the torso, later accommodate it properly:
 .. image:: img/tuto_cutout3.png
 .. image:: img/tuto_cutout3.png
 
 
 This looks good. Let's see if our hierarchy works as a skeleton by
 This looks good. Let's see if our hierarchy works as a skeleton by
-rotating the torso. We can do this be pressing ``E`` to enter rotate mode, 
+rotating the torso. We can do this be pressing ``E`` to enter rotate mode,
 and dragging with the left mouse button. To exit rotate mode hit ``ESC``.
 and dragging with the left mouse button. To exit rotate mode hit ``ESC``.
 
 
 .. image:: img/tutovec_torso1.gif
 .. image:: img/tutovec_torso1.gif
@@ -121,7 +121,7 @@ simple! Or maybe not:
 
 
 .. image:: img/tuto_cutout7.png
 .. image:: img/tuto_cutout7.png
 
 
-Right. In 2D, parent nodes appear below children nodes. Well, this sucks. 
+Right. In 2D, parent nodes appear below children nodes. Well, this sucks.
 But how can this problem be solved? We want the left arm to appear behind
 But how can this problem be solved? We want the left arm to appear behind
 the hip and the torso. For this, we can move the nodes behind the hip
 the hip and the torso. For this, we can move the nodes behind the hip
 (note that you can bypass this by setting the Node2D Z property, but then you
 (note that you can bypass this by setting the Node2D Z property, but then you
@@ -229,8 +229,8 @@ can be selected and animated.
 Finally, create endpoints in all meaningful extremities and connect the
 Finally, create endpoints in all meaningful extremities and connect the
 whole skeleton with bones up to the hip.
 whole skeleton with bones up to the hip.
 
 
-You may notice when connecting the hip and torso, that an extra bone is created. 
-To fix this, select the root and hip node, open the Skeleton menu, click ``clear bones``. 
+You may notice when connecting the hip and torso, that an extra bone is created.
+To fix this, select the root and hip node, open the Skeleton menu, click ``clear bones``.
 
 
 .. image:: img/tuto_cutout15_2.png
 .. image:: img/tuto_cutout15_2.png
 
 
@@ -354,9 +354,9 @@ Batch setting transition curves
 When creating complex animations and inserting many keyframes,
 When creating complex animations and inserting many keyframes,
 editing the individual keyframe curves for each can become an endless
 editing the individual keyframe curves for each can become an endless
 task. For this, the Animation Editor has a small menu where changing
 task. For this, the Animation Editor has a small menu where changing
-animation curves is easy. First select the appropriate keys. Next click on the 
-pencil icon in the bottom right of the animation panel, this will open the 
-transition editor. Now click on one of the curve options most appropriate for 
+animation curves is easy. First select the appropriate keys. Next click on the
+pencil icon in the bottom right of the animation panel, this will open the
+transition editor. Now click on one of the curve options most appropriate for
 your animation.
 your animation.
 
 
 .. image:: img/tuto_cutout24.png
 .. image:: img/tuto_cutout24.png

+ 14 - 14
tutorials/assetlib/uploading_to_assetlib.rst

@@ -25,37 +25,37 @@ While it may look like a lot (and there is more as you scroll down), each field
 described in terms of what you should put in. We will nonetheless go over what
 described in terms of what you should put in. We will nonetheless go over what
 is required in the submission form here as well.
 is required in the submission form here as well.
 
 
-* **Asset Name**: 
-    The name of your asset. Should be a unique, descriptive title of 
+* **Asset Name**:
+    The name of your asset. Should be a unique, descriptive title of
     what your asset is.
     what your asset is.
-* **Category**: 
+* **Category**:
     The category that your asset belongs to, and will be shown in
     The category that your asset belongs to, and will be shown in
-    search results. The category is split into **Addons** and **Projects**.  
+    search results. The category is split into **Addons** and **Projects**.
     In-editor, assets of the Project type (Templates, Demos, Projects) only show
     In-editor, assets of the Project type (Templates, Demos, Projects) only show
     up when viewing the AssetLib from the Project Manager, while assets of the
     up when viewing the AssetLib from the Project Manager, while assets of the
-    Addon type will only be visible from inside a project. 
-* **Godot version**: 
+    Addon type will only be visible from inside a project.
+* **Godot version**:
     The version of the engine that the asset works with.
     The version of the engine that the asset works with.
     Currently it's not possible to have a single asset entry contain downloads for
     Currently it's not possible to have a single asset entry contain downloads for
     multiple engine versions, so you may need to re-submit the asset multiple times,
     multiple engine versions, so you may need to re-submit the asset multiple times,
     with an entry for each Godot version it supports. This is particularly important
     with an entry for each Godot version it supports. This is particularly important
     when dealing with major versions of the engine, such as Godot 2.x and Godot 3.x.
     when dealing with major versions of the engine, such as Godot 2.x and Godot 3.x.
-* **Version**: 
+* **Version**:
     The version number of the asset. While you are free to choose
     The version number of the asset. While you are free to choose
     and use any versioning scheme that you like, you may want to look into
     and use any versioning scheme that you like, you may want to look into
     something such as `SemVer <https://semver.org>`_ if you want your asset's
     something such as `SemVer <https://semver.org>`_ if you want your asset's
     versioning scheme to be clear and consistent. Note that there is also an
     versioning scheme to be clear and consistent. Note that there is also an
     internal version number, incremented every time the asset download URL is
     internal version number, incremented every time the asset download URL is
-    changed or updated. 
-* **Repository host**: 
+    changed or updated.
+* **Repository host**:
     Assets uploaded to the AssetLib are not hosted on it
     Assets uploaded to the AssetLib are not hosted on it
     directly. Instead, they point to repositories hosted on third-party Git providers
     directly. Instead, they point to repositories hosted on third-party Git providers
     such as GitHub, GitLab or Bitbucket. This is where you choose which provider
     such as GitHub, GitLab or Bitbucket. This is where you choose which provider
     your asset uses, so the site can compute the final download link.
     your asset uses, so the site can compute the final download link.
-* **Repository URL**: 
+* **Repository URL**:
     The URL to your asset's files/webpage. This will vary
     The URL to your asset's files/webpage. This will vary
     based on your choice of provider, but it should look similar to `https://github.com/<user>/<project>`.
     based on your choice of provider, but it should look similar to `https://github.com/<user>/<project>`.
-* **Issues URL**: 
+* **Issues URL**:
     The URL to your asset's issue tracker. Again, this will differ
     The URL to your asset's issue tracker. Again, this will differ
     from repository host to repository host, but will likely look similar to
     from repository host to repository host, but will likely look similar to
     `https://github.com/<user>/<project>/issues`. You may leave this field empty
     `https://github.com/<user>/<project>/issues`. You may leave this field empty
@@ -71,7 +71,7 @@ is required in the submission form here as well.
 * **License**:
 * **License**:
     The license under which you are distributing the asset. The list
     The license under which you are distributing the asset. The list
     includes a variety of free and open-source software licenses, such as GPL
     includes a variety of free and open-source software licenses, such as GPL
-    (v2 and v3), MIT, BSD and Boost Software License. You can visit `OpenSource.org <https://opensource.org>`_  
+    (v2 and v3), MIT, BSD and Boost Software License. You can visit `OpenSource.org <https://opensource.org>`_
     for a detailed description of each of the listed licenses.
     for a detailed description of each of the listed licenses.
 * **Description**:
 * **Description**:
     Finally, you can use the Description field for a textual
     Finally, you can use the Description field for a textual
@@ -83,7 +83,7 @@ You may also include up to three video and/or image previews, which will be show
 at the bottom of the asset page. Use the "Enable" checkbox on each of the preview
 at the bottom of the asset page. Use the "Enable" checkbox on each of the preview
 submission boxes to enable them.
 submission boxes to enable them.
 
 
-* **Type**: 
+* **Type**:
     Either an image, or a video.
     Either an image, or a video.
 * **Image/YouTube URL**:
 * **Image/YouTube URL**:
     Either a link to the image, or to a video, hosted on YouTube.
     Either a link to the image, or to a video, hosted on YouTube.
@@ -97,7 +97,7 @@ which you can visit on the AssetLib `here <https://godotengine.org/asset-library
 take up to a few days for your addon to be accepted (or rejected), so please
 take up to a few days for your addon to be accepted (or rejected), so please
 be patient! You will be informed when your asset is reviewed. If it was rejected,
 be patient! You will be informed when your asset is reviewed. If it was rejected,
 you will be told why that may have been, and you will be able to submit it again
 you will be told why that may have been, and you will be able to submit it again
-with the appropriate changes. 
+with the appropriate changes.
 You may have some luck accelerating the approval process by messaging the
 You may have some luck accelerating the approval process by messaging the
 moderators/assetlib reviewers on IRC (the #godotengine-atelier channel on Freenode),
 moderators/assetlib reviewers on IRC (the #godotengine-atelier channel on Freenode),
 or the official Discord server.
 or the official Discord server.

+ 4 - 4
tutorials/assetlib/using_assetlib.rst

@@ -73,7 +73,7 @@ Now let's take a look at what an asset's page looks like and what it contains.
 Registering and logging in
 Registering and logging in
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
-In order to upload assets to the AssetLib, you need to be logged in, and to do 
+In order to upload assets to the AssetLib, you need to be logged in, and to do
 that, you need a registered user account. In the future, this may also give you
 that, you need a registered user account. In the future, this may also give you
 access to other features, such as commenting on or rating the existing assets.
 access to other features, such as commenting on or rating the existing assets.
 You do *not* need to be logged in to browse and download the assets.
 You do *not* need to be logged in to browse and download the assets.
@@ -119,13 +119,13 @@ like, with some differences:
 
 
 |image8|
 |image8|
 
 
-Similarly to the web version of the AssetLib, here you can search 
+Similarly to the web version of the AssetLib, here you can search
 for assets by category, name, and sort them by factors such as name or edit date.
 for assets by category, name, and sort them by factors such as name or edit date.
 
 
 Notably, you can only fetch assets for the current version of Godot you are running.
 Notably, you can only fetch assets for the current version of Godot you are running.
 Also, you can only download Projects, Demos and Templates from the Project Manager
 Also, you can only download Projects, Demos and Templates from the Project Manager
 view of the AssetLib, while Addons (tools, scripts, materials etc.) can only be
 view of the AssetLib, while Addons (tools, scripts, materials etc.) can only be
-downloaded from the in-project AssetLib. 
+downloaded from the in-project AssetLib.
 In addition, unlike when using the web frontend, the search results are updated
 In addition, unlike when using the web frontend, the search results are updated
 in real-time (you do not have to press Search after every change to your search
 in real-time (you do not have to press Search after every change to your search
 query for the changes to take place).
 query for the changes to take place).
@@ -155,7 +155,7 @@ Here you can see a list of all the files that will be installed. You can tick of
 any of the files that you do not wish to install, and Godot will also inform you
 any of the files that you do not wish to install, and Godot will also inform you
 about any problems with files that it cannot install. These files will be shown
 about any problems with files that it cannot install. These files will be shown
 in red, and hovering over them will show you a message stating why it cannot be
 in red, and hovering over them will show you a message stating why it cannot be
-installed. 
+installed.
 
 
 |image12|
 |image12|
 
 

+ 1 - 1
tutorials/audio/index.rst

@@ -7,4 +7,4 @@ Audio
 
 
    audio_buses
    audio_buses
    audio_streams
    audio_streams
-   
+

+ 2 - 2
tutorials/debug/overview_of_debugging_tools.rst

@@ -90,13 +90,13 @@ Listing the video memory usage of the running game.
 Misc
 Misc
 ++++
 ++++
 
 
-Miscellaneous options for debug. 
+Miscellaneous options for debug.
 
 
 
 
 Remote in Scene dock
 Remote in Scene dock
 --------------------
 --------------------
 
 
-When running your game, a bar will occur at the top of the ``Scene`` dock. You can switch to ``Remote`` and inspect or change the nodes' parameters in the running game. 
+When running your game, a bar will occur at the top of the ``Scene`` dock. You can switch to ``Remote`` and inspect or change the nodes' parameters in the running game.
 
 
 .. image:: img/overview_remote.png
 .. image:: img/overview_remote.png
 
 

+ 3 - 3
tutorials/gui/custom_gui_controls.rst

@@ -59,7 +59,7 @@ exists. Example
         {
         {
             DrawSelected()
             DrawSelected()
         }
         }
-        else 
+        else
         {
         {
             DrawNormal();
             DrawNormal();
         }
         }
@@ -83,7 +83,7 @@ for example:
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
 
 
-    func get_minimum_size(): 
+    func get_minimum_size():
         return Vector2(30, 30)
         return Vector2(30, 30)
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
@@ -207,7 +207,7 @@ exists, but can be checked with the _notification callback:
         {
         {
             case NotificationMouseEnter:
             case NotificationMouseEnter:
                 // mouse entered the area of this control
                 // mouse entered the area of this control
-                break; 
+                break;
 
 
             case NotificationMouseExit:
             case NotificationMouseExit:
                 // mouse exited the area of this control
                 // mouse exited the area of this control

+ 1 - 1
tutorials/gui/gui_skinning.rst

@@ -80,7 +80,7 @@ An example usage:
 
 
     var t = new Theme();
     var t = new Theme();
     t.SetColor("fontColor", "Label", new Color(1.0f, 1.0f, 1.0f));
     t.SetColor("fontColor", "Label", new Color(1.0f, 1.0f, 1.0f));
-    
+
     var l = new Label();
     var l = new Label();
     l.SetTheme(t);
     l.SetTheme(t);
 
 

+ 3 - 3
tutorials/inputs/custom_mouse_cursor.rst

@@ -8,7 +8,7 @@ You might want to change the appearance of the mouse cursor in your game in orde
 1. Using project settings
 1. Using project settings
 2. Using a script
 2. Using a script
 
 
-Using project settings is a simpler but more limited way to customize the mouse cursor. The second way is more customizable but involves scripting. 
+Using project settings is a simpler but more limited way to customize the mouse cursor. The second way is more customizable but involves scripting.
 
 
 Using project settings
 Using project settings
 ----------------------
 ----------------------
@@ -35,12 +35,12 @@ Create a Node and attach the following script.
     # Load the custom images for the mouse cursor
     # Load the custom images for the mouse cursor
     var arrow = load("res://arrow.png")
     var arrow = load("res://arrow.png")
     var beam = load("res://beam.png")
     var beam = load("res://beam.png")
-    
+
     func _ready():
     func _ready():
         # Changes only the arrow shape of the cursor
         # Changes only the arrow shape of the cursor
         # This is similar to changing it in the project settings
         # This is similar to changing it in the project settings
         Input.set_custom_mouse_cursor(arrow)
         Input.set_custom_mouse_cursor(arrow)
-    
+
         # Changes a specific shape of the cursor (here the IBeam shape)
         # Changes a specific shape of the cursor (here the IBeam shape)
         Input.set_custom_mouse_cursor(beam, Input.CURSOR_IBEAM)
         Input.set_custom_mouse_cursor(beam, Input.CURSOR_IBEAM)
 
 

+ 4 - 4
tutorials/inputs/inputevent.rst

@@ -77,7 +77,7 @@ received input, in order:
 1. First of all, the standard :ref:`Node._input() <class_Node__input>` function
 1. First of all, the standard :ref:`Node._input() <class_Node__input>` function
    will be called in any node that overrides it (and hasn't disabled input processing with :ref:`Node.set_process_input() <class_Node_set_process_input>`).
    will be called in any node that overrides it (and hasn't disabled input processing with :ref:`Node.set_process_input() <class_Node_set_process_input>`).
    If any function consumes the event, it can call :ref:`SceneTree.set_input_as_handled() <class_SceneTree_set_input_as_handled>`, and the event will
    If any function consumes the event, it can call :ref:`SceneTree.set_input_as_handled() <class_SceneTree_set_input_as_handled>`, and the event will
-   not spread any more. This ensures that you can filter all events of interest, even before the GUI. 
+   not spread any more. This ensures that you can filter all events of interest, even before the GUI.
    For gameplay input, :ref:`Node._unhandled_input() <class_Node__unhandled_input>` is generally a better fit, because it allows the GUI to intercept the events.
    For gameplay input, :ref:`Node._unhandled_input() <class_Node__unhandled_input>` is generally a better fit, because it allows the GUI to intercept the events.
 2. Second, it will try to feed the input to the GUI, and see if any
 2. Second, it will try to feed the input to the GUI, and see if any
    control can receive it. If so, the :ref:`Control <class_Control>` will be called via the
    control can receive it. If so, the :ref:`Control <class_Control>` will be called via the
@@ -90,7 +90,7 @@ received input, in order:
    of mouse events via :ref:`Control._gui_input() <class_Control__gui_input>`
    of mouse events via :ref:`Control._gui_input() <class_Control__gui_input>`
    callback, and whether these events are propagated further.
    callback, and whether these events are propagated further.
 3. If so far no one consumed the event, the unhandled input callback
 3. If so far no one consumed the event, the unhandled input callback
-   will be called if overridden (and not disabled with 
+   will be called if overridden (and not disabled with
    :ref:`Node.set_process_unhandled_input() <class_Node_set_process_unhandled_input>`).
    :ref:`Node.set_process_unhandled_input() <class_Node_set_process_unhandled_input>`).
    If any function consumes the event, it can call :ref:`SceneTree.set_input_as_handled() <class_SceneTree_set_input_as_handled>`, and the
    If any function consumes the event, it can call :ref:`SceneTree.set_input_as_handled() <class_SceneTree_set_input_as_handled>`, and the
    event will not spread any more. The unhandled input callback is ideal for full-screen gameplay events, so they are not received when a GUI is active.
    event will not spread any more. The unhandled input callback is ideal for full-screen gameplay events, so they are not received when a GUI is active.
@@ -150,7 +150,7 @@ There are several specialised types of InputEvent, described in the table below:
 |                                                                   |                    | information. (only available on mobile  |
 |                                                                   |                    | information. (only available on mobile  |
 |                                                                   |                    | devices)                                |
 |                                                                   |                    | devices)                                |
 +-------------------------------------------------------------------+--------------------+-----------------------------------------+
 +-------------------------------------------------------------------+--------------------+-----------------------------------------+
-| :ref:`InputEventScreenDrag <class_InputEventScreenDrag>`          | SCREEN_DRAG        | Contains multi-touch drag information.  | 
+| :ref:`InputEventScreenDrag <class_InputEventScreenDrag>`          | SCREEN_DRAG        | Contains multi-touch drag information.  |
 |                                                                   |                    | (only available on mobile devices)      |
 |                                                                   |                    | (only available on mobile devices)      |
 +-------------------------------------------------------------------+--------------------+-----------------------------------------+
 +-------------------------------------------------------------------+--------------------+-----------------------------------------+
 | :ref:`InputEventAction <class_InputEventAction>`                  | SCREEN_ACTION      | Contains a generic action. These events |
 | :ref:`InputEventAction <class_InputEventAction>`                  | SCREEN_ACTION      | Contains a generic action. These events |
@@ -185,7 +185,7 @@ The Input singleton has a method for this:
 
 
     var ev = InputEventAction.new()
     var ev = InputEventAction.new()
     # set as move_left, pressed
     # set as move_left, pressed
-    ev.set_as_action("move_left", true) 
+    ev.set_as_action("move_left", true)
     # feedback
     # feedback
     Input.parse_input_event(ev)
     Input.parse_input_event(ev)
 
 

+ 1 - 1
tutorials/io/background_loading.rst

@@ -123,7 +123,7 @@ progress bar or loading screen, etc.
         # start your "loading..." animation
         # start your "loading..." animation
         get_node("animation").play("loading")
         get_node("animation").play("loading")
 
 
-        wait_frames = 1 
+        wait_frames = 1
 
 
 ``_process`` is where the loader is polled. ``poll`` is called, and then
 ``_process`` is where the loader is polled. ``poll`` is called, and then
 we deal with the return value from that call. ``OK`` means keep polling,
 we deal with the return value from that call. ``OK`` means keep polling,

+ 2 - 2
tutorials/io/encrypting_save_games.rst

@@ -5,7 +5,7 @@ Encrypting save games
 
 
 Why?
 Why?
 ----
 ----
- 
+
 Because the world today is not the world of yesterday. A capitalist
 Because the world today is not the world of yesterday. A capitalist
 oligarchy runs the world and forces us to consume in order to keep the
 oligarchy runs the world and forces us to consume in order to keep the
 gears of this rotten society on track. As such, the biggest market for
 gears of this rotten society on track. As such, the biggest market for
@@ -33,7 +33,7 @@ How?
 ----
 ----
 
 
 The class :ref:`File <class_File>` can open a file at a
 The class :ref:`File <class_File>` can open a file at a
-location and read/write data (integers, strings and variants). 
+location and read/write data (integers, strings and variants).
 It also supports encryption.
 It also supports encryption.
 To create an encrypted file, a passphrase must be provided, like this:
 To create an encrypted file, a passphrase must be provided, like this:
 
 

+ 2 - 2
tutorials/math/matrices_and_transforms.rst

@@ -201,7 +201,7 @@ that hasn't been translated, rotated or scaled.
     var m = Transform2D()
     var m = Transform2D()
     print(m)
     print(m)
     # prints: ((1, 0), (0, 1), (0, 0))
     # prints: ((1, 0), (0, 1), (0, 0))
-    
+
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
@@ -442,7 +442,7 @@ If the matrix is orthonormal, then:
 
 
 .. tabs::
 .. tabs::
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
- 
+
     # if m is orthonormal, then
     # if m is orthonormal, then
     pos = mi.xform(pos)
     pos = mi.xform(pos)
     # is the same is
     # is the same is

+ 6 - 6
tutorials/math/vector_math.rst

@@ -158,7 +158,7 @@ the velocity to the current position.
 
 
 .. image:: img/vector_movement1.png
 .. image:: img/vector_movement1.png
 
 
-.. tip:: Velocity measures the **change** in position per unit of time. The 
+.. tip:: Velocity measures the **change** in position per unit of time. The
          new position is found by adding velocity to the previous position.
          new position is found by adding velocity to the previous position.
 
 
 - Pointing toward a target
 - Pointing toward a target
@@ -189,14 +189,14 @@ by its magnitude:
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
 
 
     var a = Vector2(2, 4)
     var a = Vector2(2, 4)
-    var m = sqrt(a.x*a.x + a.y*a.y)  # get magnitude "m" using the Pythagorean theorem 
+    var m = sqrt(a.x*a.x + a.y*a.y)  # get magnitude "m" using the Pythagorean theorem
     a.x /= m
     a.x /= m
     a.y /= m
     a.y /= m
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
 
 
     var a = new Vector2(2, 4);
     var a = new Vector2(2, 4);
-    var m = Mathf.Sqrt(a.x*a.x + a.y*a.y);  // get magnitude "m" using the Pythagorean theorem 
+    var m = Mathf.Sqrt(a.x*a.x + a.y*a.y);  // get magnitude "m" using the Pythagorean theorem
     a.x /= m;
     a.x /= m;
     a.y /= m;
     a.y /= m;
 
 
@@ -249,7 +249,7 @@ to handle this. Here is a GDScript example of the diagram above using a
         move_and_collide(reflect)
         move_and_collide(reflect)
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
-    
+
     // KinematicCollision2D contains information about the collision
     // KinematicCollision2D contains information about the collision
     KinematicCollision2D collision = MoveAndCollide(_velocity * delta);
     KinematicCollision2D collision = MoveAndCollide(_velocity * delta);
     if (collision != null)
     if (collision != null)
@@ -270,13 +270,13 @@ direction, a scalar value has only magnitude.
 The formula for dot product takes two common forms:
 The formula for dot product takes two common forms:
 
 
 .. math::
 .. math::
-    
+
     A \cdot B = \left \| A \right \|\left \| B \right \|\cos \Theta
     A \cdot B = \left \| A \right \|\left \| B \right \|\cos \Theta
 
 
 and
 and
 
 
 .. math::
 .. math::
-    
+
     A \cdot B = A_{x}B_{x} + A_{y}B_{y}
     A \cdot B = A_{x}B_{x} + A_{y}B_{y}
 
 
 However, in most cases it is easiest to use the built-in method. Note that
 However, in most cases it is easiest to use the built-in method. Note that

+ 5 - 5
tutorials/math/vectors_advanced.rst

@@ -261,7 +261,7 @@ Code should be something like this:
             break; // with one that fails, it's enough
             break; // with one that fails, it's enough
         }
         }
     }
     }
- 
+
 Pretty cool, huh? But this gets much better! With a little more effort,
 Pretty cool, huh? But this gets much better! With a little more effort,
 similar logic will let us know when two convex polygons are overlapping
 similar logic will let us know when two convex polygons are overlapping
 too. This is called the Separating Axis Theorem (or SAT) and most
 too. This is called the Separating Axis Theorem (or SAT) and most
@@ -328,7 +328,7 @@ Code should be something like this:
                     break;
                     break;
                 }
                 }
             }
             }
-            
+
             if (allOut)
             if (allOut)
             {
             {
                 // a separating plane was found
                 // a separating plane was found
@@ -353,7 +353,7 @@ Code should be something like this:
                         break;
                         break;
                     }
                     }
                 }
                 }
-                
+
                 if (allOut)
                 if (allOut)
                 {
                 {
                     overlapping = false;
                     overlapping = false;
@@ -481,7 +481,7 @@ So the final algorithm is something like:
        print("Polygons collided!")
        print("Polygons collided!")
 
 
  .. code-tab:: csharp
  .. code-tab:: csharp
- 
+
     var overlapping = true;
     var overlapping = true;
 
 
     foreach (Plane plane in planesOfA)
     foreach (Plane plane in planesOfA)
@@ -520,7 +520,7 @@ So the final algorithm is something like:
                     break;
                     break;
                 }
                 }
             }
             }
-            
+
             if (allOut)
             if (allOut)
             {
             {
                 overlapping = false;
                 overlapping = false;

+ 2 - 2
tutorials/misc/running_code_in_the_editor.rst

@@ -47,10 +47,10 @@ Here is how a ``_process()`` function might look like for you:
     func _process(delta):
     func _process(delta):
         if Engine.editor_hint:
         if Engine.editor_hint:
             # Code to execute in editor.
             # Code to execute in editor.
-        
+
         if not Engine.editor_hint:
         if not Engine.editor_hint:
             # Code to execute in game.
             # Code to execute in game.
-        
+
         # Code to execute both in editor and in game.
         # Code to execute both in editor and in game.
 
 
 .. note:: Modifications in editor are permanent. In our case, when we remove the script, the node will keep its rotation direction. Be careful so that you don't make unwanted modifications.
 .. note:: Modifications in editor are permanent. In our case, when we remove the script, the node will keep its rotation direction. Be careful so that you don't make unwanted modifications.

+ 9 - 9
tutorials/networking/high_level_multiplayer.rst

@@ -63,10 +63,10 @@ This object is not meant to be created directly, but is designed so that several
 
 
 This object extends from :ref:`PacketPeer <class_PacketPeer>`, so it inherits all the useful methods for serializing, sending and receiving data. On top of that, it adds methods to set a peer, transfer mode, etc. It also includes signals that will let you know when peers connect or disconnect.
 This object extends from :ref:`PacketPeer <class_PacketPeer>`, so it inherits all the useful methods for serializing, sending and receiving data. On top of that, it adds methods to set a peer, transfer mode, etc. It also includes signals that will let you know when peers connect or disconnect.
 
 
-This class interface can abstract most types of network layers, topologies and libraries. By default Godot 
+This class interface can abstract most types of network layers, topologies and libraries. By default Godot
 provides an implementation based on ENet (:ref:`NetworkedMultiplayerEnet <class_NetworkedMultiplayerENet>`), but this could be used to implement mobile APIs (for adhoc WiFi, Bluetooth) or custom device/console-specific networking APIs.
 provides an implementation based on ENet (:ref:`NetworkedMultiplayerEnet <class_NetworkedMultiplayerENet>`), but this could be used to implement mobile APIs (for adhoc WiFi, Bluetooth) or custom device/console-specific networking APIs.
 
 
-For most common cases, using this object directly is discouraged, as Godot provides even higher level networking facilities. 
+For most common cases, using this object directly is discouraged, as Godot provides even higher level networking facilities.
 Yet it is made available in case a game has specific needs for a lower level API.
 Yet it is made available in case a game has specific needs for a lower level API.
 
 
 Initializing the network
 Initializing the network
@@ -118,7 +118,7 @@ Terminating the networking feature:
 Managing connections
 Managing connections
 --------------------
 --------------------
 
 
-Some games accept connections at any time, others during the lobby phase. Godot can be requested to no longer accept 
+Some games accept connections at any time, others during the lobby phase. Godot can be requested to no longer accept
 connections at any point (see `set_refuse_new_network_connections(bool)` and related methods on :ref:`SceneTree <class_SceneTree>`). To manage who connects, Godot provides the following signals in SceneTree:
 connections at any point (see `set_refuse_new_network_connections(bool)` and related methods on :ref:`SceneTree <class_SceneTree>`). To manage who connects, Godot provides the following signals in SceneTree:
 
 
 Server and Clients:
 Server and Clients:
@@ -138,7 +138,7 @@ Clients:
 - `connection_failed`
 - `connection_failed`
 - `server_disconnected`
 - `server_disconnected`
 
 
-Again, all these functions are mainly useful for lobby management or for adding/removing players on the fly. 
+Again, all these functions are mainly useful for lobby management or for adding/removing players on the fly.
 For these tasks the server clearly has to work as a server and you have do tasks manually such as sending a newly connected
 For these tasks the server clearly has to work as a server and you have do tasks manually such as sending a newly connected
 player information about other already connected players (e.g. their names, stats, etc).
 player information about other already connected players (e.g. their names, stats, etc).
 
 
@@ -168,7 +168,7 @@ Functions can be called in two fashions:
 - Reliable: the function call will arrive no matter what, but may take longer because it will be re-transmitted in case of failure.
 - Reliable: the function call will arrive no matter what, but may take longer because it will be re-transmitted in case of failure.
 - Unreliable: if the function call does not arrive, it will not be re-transmitted, but if it arrives it will do it quickly.
 - Unreliable: if the function call does not arrive, it will not be re-transmitted, but if it arrives it will do it quickly.
 
 
-In most cases, reliable is desired. Unreliable is mostly useful when synchronizing object positions (sync must happen constantly, 
+In most cases, reliable is desired. Unreliable is mostly useful when synchronizing object positions (sync must happen constantly,
 and if a packet is lost, it's not that bad because a new one will eventually arrive and it would likely be outdated because the object moved further in the meantime, even if it was resent reliably).
 and if a packet is lost, it's not that bad because a new one will eventually arrive and it would likely be outdated because the object moved further in the meantime, even if it was resent reliably).
 
 
 There is also the `get_rpc_sender_id` function in `SceneTree` which can be used to check which peer (or peer ID) sent a RPC call.
 There is also the `get_rpc_sender_id` function in `SceneTree` which can be used to check which peer (or peer ID) sent a RPC call.
@@ -232,7 +232,7 @@ You might have noticed already something different, which is the usage of the `r
 ::
 ::
 
 
     remote func register_player(id, info):
     remote func register_player(id, info):
-  
+
 This keyword has two main uses. The first is to let Godot know that this function can be called from RPC. If no keywords are added
 This keyword has two main uses. The first is to let Godot know that this function can be called from RPC. If no keywords are added
 Godot will block any attempts to call functions for security. This makes security work a lot easier (so a client can't call a function
 Godot will block any attempts to call functions for security. This makes security work a lot easier (so a client can't call a function
 to delete a file on another client's system).
 to delete a file on another client's system).
@@ -252,7 +252,7 @@ The others will be explained further down.
 Note that you could also use the `get_rpc_sender_id` function on `SceneTree` to check which peer actually made the RPC call to `register_player`.
 Note that you could also use the `get_rpc_sender_id` function on `SceneTree` to check which peer actually made the RPC call to `register_player`.
 
 
 With this, lobby management should be more or less explained. Once you have your game going you will most likely want to add some
 With this, lobby management should be more or less explained. Once you have your game going you will most likely want to add some
-extra security to make sure clients don't do anything funny (just validate the info they send from time to time, or before 
+extra security to make sure clients don't do anything funny (just validate the info they send from time to time, or before
 game start). For the sake of simplicity and because each game will share different information, this is not shown here.
 game start). For the sake of simplicity and because each game will share different information, this is not shown here.
 
 
 Starting the game
 Starting the game
@@ -264,13 +264,13 @@ special in itself, but we'll explain a few nice tricks that can be done at this
 Player scenes
 Player scenes
 ^^^^^^^^^^^^^
 ^^^^^^^^^^^^^
 
 
-In most games, each player will likely have its own scene. Remember that this is a multiplayer game, so in every peer 
+In most games, each player will likely have its own scene. Remember that this is a multiplayer game, so in every peer
 you need to instance **one scene for each player connected to it**. For a 4 player game, each peer needs to instance 4 player nodes.
 you need to instance **one scene for each player connected to it**. For a 4 player game, each peer needs to instance 4 player nodes.
 
 
 So, how to name such nodes? In Godot nodes need to have an unique name. It must also be relatively easy for a player to tell which
 So, how to name such nodes? In Godot nodes need to have an unique name. It must also be relatively easy for a player to tell which
 nodes represent each player ID.
 nodes represent each player ID.
 
 
-The solution is to simply name the *root nodes of the instanced player scenes as their network ID*. This way, they will be the same in 
+The solution is to simply name the *root nodes of the instanced player scenes as their network ID*. This way, they will be the same in
 every peer and RPC will work great! Here is an example:
 every peer and RPC will work great! Here is an example:
 
 
 ::
 ::

+ 12 - 12
tutorials/physics/kinematic_character_2d.rst

@@ -69,7 +69,7 @@ or lose precision if the frame rate is too high or too low.
 
 
     public class PhysicsScript : KinematicBody2D
     public class PhysicsScript : KinematicBody2D
     {
     {
-        
+
         public override void _PhysicsProcess(float delta)
         public override void _PhysicsProcess(float delta)
         {
         {
         }
         }
@@ -85,9 +85,9 @@ for the character. Use the robot sprite and create a scene like this:
 
 
 .. image:: img/kbscene.png
 .. image:: img/kbscene.png
 
 
-You'll notice that there's a warning icon next to our CollisionShape2D node, 
-that's because we haven't defined a shape for it. Create a new CircleShape2D 
-in the shape property of CollisionShape2D. Click on <CircleShape2D> to go to the 
+You'll notice that there's a warning icon next to our CollisionShape2D node,
+that's because we haven't defined a shape for it. Create a new CircleShape2D
+in the shape property of CollisionShape2D. Click on <CircleShape2D> to go to the
 options for it, and set the radius to 30:
 options for it, and set the radius to 30:
 
 
 .. image:: img/kbradius.png
 .. image:: img/kbradius.png
@@ -121,21 +121,21 @@ collision happens, it stops right at the moment of the collision.
 So, let's move our sprite downwards until it hits the floor:
 So, let's move our sprite downwards until it hits the floor:
 
 
 .. tabs::
 .. tabs::
- .. code-tab:: gdscript GDScript 
+ .. code-tab:: gdscript GDScript
 
 
     extends KinematicBody2D
     extends KinematicBody2D
 
 
     func _physics_process(delta):
     func _physics_process(delta):
         move_and_collide(Vector2(0, 1)) # Move down 1 pixel per physics frame
         move_and_collide(Vector2(0, 1)) # Move down 1 pixel per physics frame
 
 
- .. code-tab:: csharp 
+ .. code-tab:: csharp
 
 
     using Godot;
     using Godot;
     using System;
     using System;
 
 
     public class PhysicsScript : KinematicBody2D
     public class PhysicsScript : KinematicBody2D
     {
     {
-        
+
         public override void _PhysicsProcess(float delta)
         public override void _PhysicsProcess(float delta)
         {
         {
             // Move down 1 pixel per physics frame
             // Move down 1 pixel per physics frame
@@ -150,7 +150,7 @@ The next step will be adding gravity to the mix, this way it behaves a
 little more like an actual game character:
 little more like an actual game character:
 
 
 .. tabs::
 .. tabs::
- .. code-tab:: gdscript GDScript 
+ .. code-tab:: gdscript GDScript
 
 
     extends KinematicBody2D
     extends KinematicBody2D
 
 
@@ -163,7 +163,7 @@ little more like an actual game character:
         var motion = velocity * delta
         var motion = velocity * delta
         move_and_collide(motion)
         move_and_collide(motion)
 
 
- .. code-tab:: csharp 
+ .. code-tab:: csharp
 
 
     using Godot;
     using Godot;
     using System;
     using System;
@@ -207,14 +207,14 @@ This adds simple walking support by pressing left and right:
             velocity.x =  WALK_SPEED
             velocity.x =  WALK_SPEED
         else:
         else:
             velocity.x = 0
             velocity.x = 0
-        
+
         # We don't need to multiply velocity by delta because MoveAndSlide already takes delta time into account.
         # We don't need to multiply velocity by delta because MoveAndSlide already takes delta time into account.
 
 
         # The second parameter of move_and_slide is the normal pointing up.
         # The second parameter of move_and_slide is the normal pointing up.
         # In the case of a 2d platformer, in Godot upward is negative y, which translates to -1 as a normal.
         # In the case of a 2d platformer, in Godot upward is negative y, which translates to -1 as a normal.
         move_and_slide(velocity, Vector2(0, -1))
         move_and_slide(velocity, Vector2(0, -1))
 
 
- .. code-tab:: csharp 
+ .. code-tab:: csharp
 
 
     using Godot;
     using Godot;
     using System;
     using System;
@@ -246,7 +246,7 @@ This adds simple walking support by pressing left and right:
             // We don't need to multiply velocity by delta because MoveAndSlide already takes delta time into account.
             // We don't need to multiply velocity by delta because MoveAndSlide already takes delta time into account.
 
 
             // The second parameter of MoveAndSlide is the normal pointing up.
             // The second parameter of MoveAndSlide is the normal pointing up.
-            // In the case of a 2d platformer, in Godot upward is negative y, which translates to -1 as a normal. 
+            // In the case of a 2d platformer, in Godot upward is negative y, which translates to -1 as a normal.
             MoveAndSlide(velocity, new Vector2(0, -1));
             MoveAndSlide(velocity, new Vector2(0, -1));
         }
         }
     }
     }

+ 7 - 7
tutorials/physics/physics_introduction.rst

@@ -60,7 +60,7 @@ and to detect contact with other objects.
 
 
 .. note:: In order to detect collisions, at least one ``Shape2D`` must be
 .. note:: In order to detect collisions, at least one ``Shape2D`` must be
           assigned to the object.
           assigned to the object.
-          
+
 The most common way to assign a shape is by adding a :ref:`CollisionShape2D <class_CollisionShape2D>`
 The most common way to assign a shape is by adding a :ref:`CollisionShape2D <class_CollisionShape2D>`
 or :ref:`CollisionPolygon2D <class_CollisionPolygon2D>` as a child of the object.
 or :ref:`CollisionPolygon2D <class_CollisionPolygon2D>` as a child of the object.
 These nodes allow you to draw the shape directly in the editor workspace.
 These nodes allow you to draw the shape directly in the editor workspace.
@@ -85,7 +85,7 @@ In order to avoid this inaccuracy, any code that needs to access a body's proper
 be run in the :ref:`Node._physics_process() <class_Node__physics_process>`
 be run in the :ref:`Node._physics_process() <class_Node__physics_process>`
 callback, which is called before each physics step at a constant frame rate
 callback, which is called before each physics step at a constant frame rate
 (60 times per second by default).
 (60 times per second by default).
-        
+
 Collision Layers and Masks
 Collision Layers and Masks
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 
@@ -183,7 +183,7 @@ that is overriding the global physics properties.
 When a rigid body is at rest and hasn't moved for a time, it goes to sleep.
 When a rigid body is at rest and hasn't moved for a time, it goes to sleep.
 A sleeping body acts like a static body, and its forces are not calculated by
 A sleeping body acts like a static body, and its forces are not calculated by
 the physics engine. The body will wake up when forces are applied, either by
 the physics engine. The body will wake up when forces are applied, either by
-a collision or via code. 
+a collision or via code.
 
 
 Rigid body modes
 Rigid body modes
 ~~~~~~~~~~~~~~~~
 ~~~~~~~~~~~~~~~~
@@ -318,9 +318,9 @@ occurred:
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
 
 
     extends KinematicBody2D
     extends KinematicBody2D
-    
+
     var velocity = Vector2(250, 250)
     var velocity = Vector2(250, 250)
-    
+
     func _physics_process(delta):
     func _physics_process(delta):
         var collision_info = move_and_collide(velocity * delta)
         var collision_info = move_and_collide(velocity * delta)
         if collision_info:
         if collision_info:
@@ -348,9 +348,9 @@ Or to bounce off of the colliding object:
  .. code-tab:: gdscript GDScript
  .. code-tab:: gdscript GDScript
 
 
     extends KinematicBody2D
     extends KinematicBody2D
-    
+
     var velocity = Vector2(250, 250)
     var velocity = Vector2(250, 250)
-    
+
     func _physics_process(delta):
     func _physics_process(delta):
         var collision_info = move_and_collide(velocity * delta)
         var collision_info = move_and_collide(velocity * delta)
         if collision_info:
         if collision_info:

+ 6 - 6
tutorials/platform/android_in_app_purchases.rst

@@ -29,16 +29,16 @@ When starting our game, we will need to get the item details from Google such as
 
 
     #First listen to the sku details update callback
     #First listen to the sku details update callback
     IAP.connect("sku_details_complete",self,"sku_details_complete")
     IAP.connect("sku_details_complete",self,"sku_details_complete")
-    
+
     #Then ask google the details for these items
     #Then ask google the details for these items
     IAP.sku_details_query(["pid1","pid2"]) #pid1 and pid2 are our product ids entered in Googleplay dashboard
     IAP.sku_details_query(["pid1","pid2"]) #pid1 and pid2 are our product ids entered in Googleplay dashboard
-    
-    
+
+
     #This will be called when sku details are retrieved successfully
     #This will be called when sku details are retrieved successfully
     func sku_details_complete():
     func sku_details_complete():
         print(IAP.sku_details) #This will print the details as JSON format, refer the format in iap.gd
         print(IAP.sku_details) #This will print the details as JSON format, refer the format in iap.gd
         print(IAP.sku_details["pid1"].price) #print formatted localized price
         print(IAP.sku_details["pid1"].price) #print formatted localized price
-        
+
 We can use the IAP details to display the title, price and/or description on our shop scene.
 We can use the IAP details to display the title, price and/or description on our shop scene.
 
 
 Check if user purchased an item
 Check if user purchased an item
@@ -89,7 +89,7 @@ We can also implement other signals for the purchase flow and improve the user e
 Consumables and Non-Consumables
 Consumables and Non-Consumables
 -------------------------------
 -------------------------------
 
 
-There are two types of products - consumables and non-consumables. 
+There are two types of products - consumables and non-consumables.
 **Consumables** are purchased and used, for eg: healing potions which can be purchased again and again.
 **Consumables** are purchased and used, for eg: healing potions which can be purchased again and again.
 **Non-consumables** are one time purchases, for eg: Level packs.
 **Non-consumables** are one time purchases, for eg: Level packs.
 
 
@@ -108,7 +108,7 @@ If our game has only consumables, we don't have to do this. We can set it to con
 ::
 ::
 
 
     IAP.set_auto_consume(true)
     IAP.set_auto_consume(true)
-    
+
 If our game has only non-consumables, we can
 If our game has only non-consumables, we can
 
 
 ::
 ::

+ 1 - 1
tutorials/plugins/editor/import_plugins.rst

@@ -311,7 +311,7 @@ that the import wasn't successful.
         return ERR_PARSE_ERROR
         return ERR_PARSE_ERROR
 
 
     var color
     var color
-    if options.use_red_anyway: 
+    if options.use_red_anyway:
         color = Color8(255, 0, 0)
         color = Color8(255, 0, 0)
     else:
     else:
         color = Color8(int(channels[0]), int(channels[1]), int(channels[2]))
         color = Color8(int(channels[0]), int(channels[1]), int(channels[2]))

+ 1 - 1
tutorials/plugins/gdnative/files/cpp_example/SConstruct

@@ -7,7 +7,7 @@ bits = ARGUMENTS.get("bits", 64)
 
 
 final_lib_path = 'demo/bin/'
 final_lib_path = 'demo/bin/'
 
 
-# This makes sure to keep the session environment variables on windows, 
+# This makes sure to keep the session environment variables on windows,
 # that way you can run scons in a vs 2017 prompt and it will find all the required tools
 # that way you can run scons in a vs 2017 prompt and it will find all the required tools
 env = Environment()
 env = Environment()
 if platform == "windows":
 if platform == "windows":

+ 2 - 2
tutorials/plugins/gdnative/gdnative-cpp-example.rst

@@ -38,7 +38,7 @@ See also :ref:`Compiling <toc-devel-compiling>` as the build tools are identical
 to the ones you need to compile Godot from source.
 to the ones you need to compile Godot from source.
 
 
 You can download these repositories from GitHub or let Git
 You can download these repositories from GitHub or let Git
-do the work for you. 
+do the work for you.
 Note that these repositories now have different branches for different versions of Godot. GDNative modules written for an earlier version of Godot will work in newer versions (with the exception of one breaking change in ARVR interfaces between 3.0 and 3.1) but not vise versa so make sure you download the correct branch.
 Note that these repositories now have different branches for different versions of Godot. GDNative modules written for an earlier version of Godot will work in newer versions (with the exception of one breaking change in ARVR interfaces between 3.0 and 3.1) but not vise versa so make sure you download the correct branch.
 
 
 If you are versioning your project using Git,
 If you are versioning your project using Git,
@@ -69,7 +69,7 @@ Do make sure you clone recursive to pull in both repositories:
 
 
 .. note:: The ``-b 3.0`` I've added as an example to show how to select a specific branch for a specific version of Godot.
 .. note:: The ``-b 3.0`` I've added as an example to show how to select a specific branch for a specific version of Godot.
           Also ``godot-cpp`` now includes ``godot_headers`` as a nested submodule, if you've manually downloaded them please make sure to place ``godot_headers`` inside of the ``godot-cpp`` folder.
           Also ``godot-cpp`` now includes ``godot_headers`` as a nested submodule, if you've manually downloaded them please make sure to place ``godot_headers`` inside of the ``godot-cpp`` folder.
-          
+
           You don't have to do it this way but I've found it easiest to manage. If you decide to just download the repositories or just clone them into your folder, makes sure to keep the folder layout the same as I've setup here as much of the code we'll be showcasing here assumes the project has this layout.
           You don't have to do it this way but I've found it easiest to manage. If you decide to just download the repositories or just clone them into your folder, makes sure to keep the folder layout the same as I've setup here as much of the code we'll be showcasing here assumes the project has this layout.
 
 
 If you cloned the example from the link specified in
 If you cloned the example from the link specified in

+ 37 - 37
tutorials/shading/migrating_to_godot_shader_language.rst

@@ -22,18 +22,18 @@ Accordingly, most features available in GLSL are available in Godot's shading la
 Shader Programs
 Shader Programs
 ^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^
 
 
-In GLSL each shader uses a separate program. You have one program for the vertex shader and one 
-for the fragment shader. In Godot you have a single shader that contains a ``vertex`` and/or a 
-``fragment`` function. If you only choose to write one, Godot will supply the other. 
+In GLSL each shader uses a separate program. You have one program for the vertex shader and one
+for the fragment shader. In Godot you have a single shader that contains a ``vertex`` and/or a
+``fragment`` function. If you only choose to write one, Godot will supply the other.
 
 
-Godot allows uniform variables and functions to be shared by defining the fragment and vertex 
-shaders in one file. In GLSL the vertex and fragment programs cannot share variables except 
+Godot allows uniform variables and functions to be shared by defining the fragment and vertex
+shaders in one file. In GLSL the vertex and fragment programs cannot share variables except
 when varyings are used.
 when varyings are used.
 
 
 Vertex attributes
 Vertex attributes
 ^^^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^^^
 
 
-In GLSL you can pass in per-vertex information using attributes. In GLSL you have the flexibility to 
+In GLSL you can pass in per-vertex information using attributes. In GLSL you have the flexibility to
 pass in as much or as little as you want. In Godot you have a set number of input attributes
 pass in as much or as little as you want. In Godot you have a set number of input attributes
 including, ``VERTEX`` (position), ``COLOR``, ``UV``, ``UV2``, ``NORMAL``. For a complete list
 including, ``VERTEX`` (position), ``COLOR``, ``UV``, ``UV2``, ``NORMAL``. For a complete list
 see the :ref:`Shading language reference <doc_shading_language>`.
 see the :ref:`Shading language reference <doc_shading_language>`.
@@ -41,17 +41,17 @@ see the :ref:`Shading language reference <doc_shading_language>`.
 gl_Position
 gl_Position
 ^^^^^^^^^^^
 ^^^^^^^^^^^
 
 
-``gl_Position`` receives the final position of a vertex specified in the vertex shader. 
-It is specified by the user in clip space. Typically in GLSL the model space vertex position 
-is passed in using a vertex attribute called ``position`` and you handle the 
-conversion from model space to clip space manually. 
+``gl_Position`` receives the final position of a vertex specified in the vertex shader.
+It is specified by the user in clip space. Typically in GLSL the model space vertex position
+is passed in using a vertex attribute called ``position`` and you handle the
+conversion from model space to clip space manually.
 
 
 In Godot ``VERTEX`` specifies the vertex position in model space at the beginning of the ``vertex``
 In Godot ``VERTEX`` specifies the vertex position in model space at the beginning of the ``vertex``
-function. Godot also handles the final conversion to clip space after the user-defined ``vertex`` 
-function is run. If you want to skip the conversion from model to view space, you can set the 
-``render_mode`` to ``skip_vertex_transform``. If you want to skip all transforms, set 
-``render_mode`` to ``skip_vertex_transform`` and set the ``PROJECTION_MATRIX`` to ``mat4(1.0)`` 
-in order to nullify the final transform from view space to clip space. 
+function. Godot also handles the final conversion to clip space after the user-defined ``vertex``
+function is run. If you want to skip the conversion from model to view space, you can set the
+``render_mode`` to ``skip_vertex_transform``. If you want to skip all transforms, set
+``render_mode`` to ``skip_vertex_transform`` and set the ``PROJECTION_MATRIX`` to ``mat4(1.0)``
+in order to nullify the final transform from view space to clip space.
 
 
 Varyings
 Varyings
 ^^^^^^^^
 ^^^^^^^^
@@ -63,15 +63,15 @@ out of the vertex shader is defined with ``out`` in the vertex shader and ``in``
 Main
 Main
 ^^^^
 ^^^^
 
 
-In GLSL each shader program looks like a self-contained C-style program. Accordingly, the main entry point 
-is ``main``. If you are copying a vertex shader, rename ``main`` to ``vertex`` and if you are copying a 
+In GLSL each shader program looks like a self-contained C-style program. Accordingly, the main entry point
+is ``main``. If you are copying a vertex shader, rename ``main`` to ``vertex`` and if you are copying a
 fragment shader, rename ``main`` to ``fragment``.
 fragment shader, rename ``main`` to ``fragment``.
 
 
 Constants
 Constants
 ^^^^^^^^^
 ^^^^^^^^^
 
 
 Godot currently does not support constants. You can fake the functionality by using a uniform initialized
 Godot currently does not support constants. You can fake the functionality by using a uniform initialized
-to the value, but you will not benefit from the increased speed from using a constant. 
+to the value, but you will not benefit from the increased speed from using a constant.
 
 
 Macros
 Macros
 ^^^^^^
 ^^^^^^
@@ -79,14 +79,14 @@ Macros
 In keeping with its similarity to C, GLSL lets you use macros. Commonly ``#define`` is used to define
 In keeping with its similarity to C, GLSL lets you use macros. Commonly ``#define`` is used to define
 constants or small functions. There is no straightforward way to translate defines to Godot's shading language.
 constants or small functions. There is no straightforward way to translate defines to Godot's shading language.
 If it is a function that is defined, then replace with a function, and if it is a constant then replace with
 If it is a function that is defined, then replace with a function, and if it is a constant then replace with
-a uniform. For other macros (``#if``, ``#ifdef``, etc.) there is no equivalent because they run during the 
+a uniform. For other macros (``#if``, ``#ifdef``, etc.) there is no equivalent because they run during the
 pre-processing stage of compilation.
 pre-processing stage of compilation.
 
 
 Variables
 Variables
 ^^^^^^^^^
 ^^^^^^^^^
 
 
 GLSL has many built in variables that are hard-coded. These variables are not uniforms, so they
 GLSL has many built in variables that are hard-coded. These variables are not uniforms, so they
-are not editable from the main program. 
+are not editable from the main program.
 
 
 +---------------------+---------+------------------------+-----------------------------------------------------+
 +---------------------+---------+------------------------+-----------------------------------------------------+
 |Variable             |Type     |Equivalent              |Description                                          |
 |Variable             |Type     |Equivalent              |Description                                          |
@@ -102,20 +102,20 @@ are not editable from the main program.
 |gl_PointCoord        |vec2     |POINT_COORD             |Position on point when drawing Point primitives.     |
 |gl_PointCoord        |vec2     |POINT_COORD             |Position on point when drawing Point primitives.     |
 +---------------------+---------+------------------------+-----------------------------------------------------+
 +---------------------+---------+------------------------+-----------------------------------------------------+
 |gl_FrontFacing       |bool     |FRONT_FACING            |True if front face of primitive.                     |
 |gl_FrontFacing       |bool     |FRONT_FACING            |True if front face of primitive.                     |
-+---------------------+---------+------------------------+-----------------------------------------------------+ 
++---------------------+---------+------------------------+-----------------------------------------------------+
 
 
 .. _glsl_coordinates:
 .. _glsl_coordinates:
 
 
 Coordinates
 Coordinates
 ^^^^^^^^^^^
 ^^^^^^^^^^^
 
 
-``gl_FragCoord`` in GLSL and ``FRAGCOORD`` in the Godot shading language use the same coordinate system. 
+``gl_FragCoord`` in GLSL and ``FRAGCOORD`` in the Godot shading language use the same coordinate system.
 If using UV in Godot, the y-coordinate will be flipped upside down.
 If using UV in Godot, the y-coordinate will be flipped upside down.
 
 
 Precision
 Precision
 ^^^^^^^^^
 ^^^^^^^^^
 
 
-In GLSL you can define the precision of a given type (float or int) at the top of the shader with the 
+In GLSL you can define the precision of a given type (float or int) at the top of the shader with the
 ``precision`` keyword. In Godot you can set the precision of individual variables as you need by placing
 ``precision`` keyword. In Godot you can set the precision of individual variables as you need by placing
 precision qualifiers ``lowp``, ``mediump``, and ``highp`` before the type when defining the variable. For
 precision qualifiers ``lowp``, ``mediump``, and ``highp`` before the type when defining the variable. For
 more information see the :ref:`Shading Language <doc_shading_language>` reference.
 more information see the :ref:`Shading Language <doc_shading_language>` reference.
@@ -123,7 +123,7 @@ more information see the :ref:`Shading Language <doc_shading_language>` referenc
 Shadertoy
 Shadertoy
 ---------
 ---------
 
 
-`Shadertoy <https://www.shadertoy.com>`_ is a website that makes it easy to write fragment shaders and 
+`Shadertoy <https://www.shadertoy.com>`_ is a website that makes it easy to write fragment shaders and
 create `pure magic <https://www.shadertoy.com/view/4tjGRh>`_.
 create `pure magic <https://www.shadertoy.com/view/4tjGRh>`_.
 
 
 Shadertoy does not give the user full control over the shader. It only allows the user to write a
 Shadertoy does not give the user full control over the shader. It only allows the user to write a
@@ -139,18 +139,18 @@ has the regular types, including `Constants`_ and macros.
 mainImage
 mainImage
 ^^^^^^^^^
 ^^^^^^^^^
 The main point of entry to a Shadertoy shader is the ``mainImage`` function. ``mainImage`` has two
 The main point of entry to a Shadertoy shader is the ``mainImage`` function. ``mainImage`` has two
-parameters, ``fragColor`` and ``fragCoord`` which correspond to ``COLOR`` and ``FRAGCOORD`` in Godot 
+parameters, ``fragColor`` and ``fragCoord`` which correspond to ``COLOR`` and ``FRAGCOORD`` in Godot
 respectively. These parameters are handled automatically in Godot, so you do not need to include them
 respectively. These parameters are handled automatically in Godot, so you do not need to include them
 as parameters yourself. Anything in the ``mainImage`` function should be copied into the ``fragment``
 as parameters yourself. Anything in the ``mainImage`` function should be copied into the ``fragment``
 function when porting to Godot.
 function when porting to Godot.
 
 
 Variables
 Variables
 ^^^^^^^^^
 ^^^^^^^^^
-In order to make writing fragment shaders straightforward and easy, Shadertoy handles passing a lot 
-of helpful information from the main program into the fragment shader for you. A few of these 
-have no equivalents in Godot because Godot has chosen not to make them available by default. 
-This is okay because Godot gives you the ability to make your own uniforms. For variables whose 
-equivalents are listed as "Provide with Uniform", the user is responsible for creating that 
+In order to make writing fragment shaders straightforward and easy, Shadertoy handles passing a lot
+of helpful information from the main program into the fragment shader for you. A few of these
+have no equivalents in Godot because Godot has chosen not to make them available by default.
+This is okay because Godot gives you the ability to make your own uniforms. For variables whose
+equivalents are listed as "Provide with Uniform", the user is responsible for creating that
 uniform themself. The description gives the reader a hint about what they can pass in as a substitute.
 uniform themself. The description gives the reader a hint about what they can pass in as a substitute.
 
 
 +---------------------+---------+------------------------+-----------------------------------------------------+
 +---------------------+---------+------------------------+-----------------------------------------------------+
@@ -176,7 +176,7 @@ uniform themself. The description gives the reader a hint about what they can pa
 +---------------------+---------+------------------------+-----------------------------------------------------+
 +---------------------+---------+------------------------+-----------------------------------------------------+
 |iChannelResolution[4]|vec3     |1.0 / TEXTURE_PIXEL_SIZE|Resolution of particular texture.                    |
 |iChannelResolution[4]|vec3     |1.0 / TEXTURE_PIXEL_SIZE|Resolution of particular texture.                    |
 +---------------------+---------+------------------------+-----------------------------------------------------+
 +---------------------+---------+------------------------+-----------------------------------------------------+
-|iChanneli            |Sampler2D|TEXTURE                 |Godot provides only one built in, user can make more.| 
+|iChanneli            |Sampler2D|TEXTURE                 |Godot provides only one built in, user can make more.|
 +---------------------+---------+------------------------+-----------------------------------------------------+
 +---------------------+---------+------------------------+-----------------------------------------------------+
 
 
 Coordinates
 Coordinates
@@ -188,11 +188,11 @@ Coordinates
 The Book of Shaders
 The Book of Shaders
 -------------------
 -------------------
 
 
-Similar to Shadertoy, `The Book of Shaders <https://thebookofshaders.com>`_ provides access to a fragment 
-shader in the web browser for the user to interact with. The user is restricted to writing fragment 
-shader code with a set list of uniforms passed in and with no ability to add additional uniforms. 
+Similar to Shadertoy, `The Book of Shaders <https://thebookofshaders.com>`_ provides access to a fragment
+shader in the web browser for the user to interact with. The user is restricted to writing fragment
+shader code with a set list of uniforms passed in and with no ability to add additional uniforms.
 
 
-For further help on porting shaders to various frameworks generally, The Book of Shaders provides 
+For further help on porting shaders to various frameworks generally, The Book of Shaders provides
 a `page <https://thebookofshaders.com/04>`_ on running shaders in various frameworks.
 a `page <https://thebookofshaders.com/04>`_ on running shaders in various frameworks.
 
 
 Types
 Types
@@ -210,8 +210,8 @@ a Book of Shaders ``main`` function should be copied into Godot's ``fragment`` f
 Variables
 Variables
 ^^^^^^^^^
 ^^^^^^^^^
 
 
-The Book of Shaders sticks closer to plain GLSL than Shadertoy does. It also implements fewer uniforms than 
-Shadertoy. 
+The Book of Shaders sticks closer to plain GLSL than Shadertoy does. It also implements fewer uniforms than
+Shadertoy.
 
 
 +---------------------+---------+------------------------+-----------------------------------------------------+
 +---------------------+---------+------------------------+-----------------------------------------------------+
 |Variable             |Type     |Equivalent              |Description                                          |
 |Variable             |Type     |Equivalent              |Description                                          |

+ 1 - 1
tutorials/shading/shader_materials.rst

@@ -9,7 +9,7 @@ Introduction
 For the most common cases, Godot provides ready to use materials for
 For the most common cases, Godot provides ready to use materials for
 most types of shaders, such as SpatialMaterial, CanvasItemMaterial and
 most types of shaders, such as SpatialMaterial, CanvasItemMaterial and
 ParticlesMaterial (@TODO link to tutorials/classes). They are flexible implementations that cover most
 ParticlesMaterial (@TODO link to tutorials/classes). They are flexible implementations that cover most
-use cases. 
+use cases.
 
 
 Shader materials allow writing a custom shader directly, for maximum flexibility.
 Shader materials allow writing a custom shader directly, for maximum flexibility.
 Examples of this are:
 Examples of this are:

+ 3 - 3
tutorials/viewports/multiple_resolutions.rst

@@ -81,7 +81,7 @@ demonstrate the effect of different stretch modes. A single sprite, also
    directly at the target resolution. 3D will be largely unaffected,
    directly at the target resolution. 3D will be largely unaffected,
    while in 2D there is no longer a 1:1 correspondence between sprite
    while in 2D there is no longer a 1:1 correspondence between sprite
    pixels and screen pixels, which may result in scaling artifacts.
    pixels and screen pixels, which may result in scaling artifacts.
-   
+
    This is a good option if your 2D artwork has a sufficiently high
    This is a good option if your 2D artwork has a sufficiently high
    resolution and does not require pixel-perfect rendering. Consider
    resolution and does not require pixel-perfect rendering. Consider
    enabling texture filtering and mipmapping on your 2D textures and
    enabling texture filtering and mipmapping on your 2D textures and
@@ -138,7 +138,7 @@ to the region outside the blue frame you see in the 2D editor.
    taller than the base resolution, the viewport will be grown in the
    taller than the base resolution, the viewport will be grown in the
    vertical direction (and more content will be visible to the bottom).
    vertical direction (and more content will be visible to the bottom).
    You can also think of this as "Expand Vertically".
    You can also think of this as "Expand Vertically".
-   
+
    This is usually the best option for creating GUIs or HUDs that scale,
    This is usually the best option for creating GUIs or HUDs that scale,
    so some controls can be anchored to the bottom
    so some controls can be anchored to the bottom
    (:ref:`doc_size_and_anchors`).
    (:ref:`doc_size_and_anchors`).
@@ -151,7 +151,7 @@ to the region outside the blue frame you see in the 2D editor.
    screen is wider than the base resolution, the viewport will be grown
    screen is wider than the base resolution, the viewport will be grown
    in the horizontal direction (and more content will be visible to the
    in the horizontal direction (and more content will be visible to the
    right). You can also think of this as "Expand Horizontally".
    right). You can also think of this as "Expand Horizontally".
-   
+
    This is usually the best option for 2D games that scroll horizontally
    This is usually the best option for 2D games that scroll horizontally
    (like runners or platformers).
    (like runners or platformers).
 
 

+ 35 - 35
tutorials/viewports/using_viewport_as_texture.rst

@@ -15,9 +15,9 @@ of making a procedural planet like the one below:
 .. note:: This tutorial does not cover how to code a dynamic atmosphere like the one this planet has.
 .. note:: This tutorial does not cover how to code a dynamic atmosphere like the one this planet has.
 
 
 This tutorial assumes you are familiar with how to set up a basic scene including:
 This tutorial assumes you are familiar with how to set up a basic scene including:
-a :ref:`Camera <class_Camera>`, a :ref:`light source <class_OmniLight>`, a 
-:ref:`Mesh Instance <class_MeshInstance>` with a :ref:`Primitive Mesh <class_PrimitiveMesh>`, 
-and applying a :ref:`Spatial Material <class_SpatialMaterial>` to the mesh. The focus will be on using 
+a :ref:`Camera <class_Camera>`, a :ref:`light source <class_OmniLight>`, a
+:ref:`Mesh Instance <class_MeshInstance>` with a :ref:`Primitive Mesh <class_PrimitiveMesh>`,
+and applying a :ref:`Spatial Material <class_SpatialMaterial>` to the mesh. The focus will be on using
 the :ref:`Viewport <class_Viewport>` to dynamically create textures that can be applied to the mesh.
 the :ref:`Viewport <class_Viewport>` to dynamically create textures that can be applied to the mesh.
 
 
 During the course of this tutorial will cover the following topics:
 During the course of this tutorial will cover the following topics:
@@ -32,15 +32,15 @@ Setting up the Viewport
 
 
 First, add a :ref:`Viewport <class_Viewport>` to the scene.
 First, add a :ref:`Viewport <class_Viewport>` to the scene.
 
 
-Next, set the size of the :ref:`Viewport <class_Viewport>` to ``(1024, 512)``. The 
-:ref:`Viewport <class_Viewport>` can actually be any size so long as the width is double the height. 
-The width needs to be double the height so that the image will accurately map onto the 
+Next, set the size of the :ref:`Viewport <class_Viewport>` to ``(1024, 512)``. The
+:ref:`Viewport <class_Viewport>` can actually be any size so long as the width is double the height.
+The width needs to be double the height so that the image will accurately map onto the
 sphere as we will be using equirectangular projection, but more on that later.
 sphere as we will be using equirectangular projection, but more on that later.
 
 
 .. image:: img/planet_new_viewport.png
 .. image:: img/planet_new_viewport.png
 
 
 Next, disable HDR and disable 3D. We don't need HDR because our planets surface will not be especially
 Next, disable HDR and disable 3D. We don't need HDR because our planets surface will not be especially
-bright so values between ``0`` and ``1`` will be fine. And we will be using a :ref:`ColorRect <class_ColorRect>` 
+bright so values between ``0`` and ``1`` will be fine. And we will be using a :ref:`ColorRect <class_ColorRect>`
 to render the surface, so we don't need 3D either.
 to render the surface, so we don't need 3D either.
 
 
 Select the Viewport and add a :ref:`ColorRect <class_ColorRect>` as a child.
 Select the Viewport and add a :ref:`ColorRect <class_ColorRect>` as a child.
@@ -73,12 +73,12 @@ apply to the sphere.
 Applying the texture
 Applying the texture
 --------------------
 --------------------
 
 
-Now we go into the :ref:`Mesh Instance <class_MeshInstance>` and add a :ref:`Spatial Material <class_SpatialMaterial>` 
-to it. No need for a special :ref:`Shader Material <class_ShaderMaterial>` (although that would be a good idea 
+Now we go into the :ref:`Mesh Instance <class_MeshInstance>` and add a :ref:`Spatial Material <class_SpatialMaterial>`
+to it. No need for a special :ref:`Shader Material <class_ShaderMaterial>` (although that would be a good idea
 for more advanced effects, like the atmosphere in the example above).
 for more advanced effects, like the atmosphere in the example above).
 
 
 Open the newly created :ref:`Spatial Material <class_SpatialMaterial>` and scroll down to the "Albedo" section
 Open the newly created :ref:`Spatial Material <class_SpatialMaterial>` and scroll down to the "Albedo" section
-and click beside the "Texture" property to add an Albedo Texture. Here we will apply the texture we made. 
+and click beside the "Texture" property to add an Albedo Texture. Here we will apply the texture we made.
 Choose "New ViewportTexture"
 Choose "New ViewportTexture"
 
 
 .. image:: img/planet_new_viewport_texture.png
 .. image:: img/planet_new_viewport_texture.png
@@ -92,16 +92,16 @@ Your sphere should now be colored in with the colors we rendered to the Viewport
 .. image:: img/planet_seam.png
 .. image:: img/planet_seam.png
 
 
 Notice the ugly seam that forms where the texture wraps around? This is because we are picking
 Notice the ugly seam that forms where the texture wraps around? This is because we are picking
-a color based on UV coordinates and UV coordinates do not wrap around the texture. This is a classic 
-problem in 2D map projection. Gamedevs often have a 2-dimensional map they want to project 
-onto a sphere but when it wraps around it has large seams. There is an elegant work around for this 
+a color based on UV coordinates and UV coordinates do not wrap around the texture. This is a classic
+problem in 2D map projection. Gamedevs often have a 2-dimensional map they want to project
+onto a sphere but when it wraps around it has large seams. There is an elegant work around for this
 problem that we will illustrate in the next section.
 problem that we will illustrate in the next section.
 
 
 Making the planet texture
 Making the planet texture
 -------------------------
 -------------------------
 
 
 So now when we render to our :ref:`Viewport <class_Viewport>` it appears magically on the sphere. But there is an ugly
 So now when we render to our :ref:`Viewport <class_Viewport>` it appears magically on the sphere. But there is an ugly
-seam created by our texture coordinates. So how do we get a range of coordinates that wrap around 
+seam created by our texture coordinates. So how do we get a range of coordinates that wrap around
 the sphere in a nice way? One solution is to use a function that repeats on the domain of our texture.
 the sphere in a nice way? One solution is to use a function that repeats on the domain of our texture.
 ``sin`` and ``cos`` are two such functions. Lets apply them to the texture and see what happens
 ``sin`` and ``cos`` are two such functions. Lets apply them to the texture and see what happens
 
 
@@ -111,10 +111,10 @@ the sphere in a nice way? One solution is to use a function that repeats on the
 
 
 .. image:: img/planet_sincos.png
 .. image:: img/planet_sincos.png
 
 
-Not too bad. If you look around you can see that the seam has now disappeared, but in its place we 
+Not too bad. If you look around you can see that the seam has now disappeared, but in its place we
 have pinching at the poles. This pinching is due to the way Godot maps textures to spheres in its
 have pinching at the poles. This pinching is due to the way Godot maps textures to spheres in its
-:ref:`Spatial Material <class_SpatialMaterial>`. It uses a projection technique called equirectangular 
-projection. Which translates a spherical map onto a 2D plane. 
+:ref:`Spatial Material <class_SpatialMaterial>`. It uses a projection technique called equirectangular
+projection. Which translates a spherical map onto a 2D plane.
 
 
 .. note:: If you are interested in a little extra information on the technique, we will be converting from
 .. note:: If you are interested in a little extra information on the technique, we will be converting from
           spherical coordinates into Cartesian coordinates. Spherical coordinates map the longitude and
           spherical coordinates into Cartesian coordinates. Spherical coordinates map the longitude and
@@ -123,8 +123,8 @@ projection. Which translates a spherical map onto a 2D plane.
 
 
 For each pixel we will calculate its 3D position on the sphere. From that we will use
 For each pixel we will calculate its 3D position on the sphere. From that we will use
 3D noise to determine a color value. By calculating the noise in 3D we solve the problem
 3D noise to determine a color value. By calculating the noise in 3D we solve the problem
-of the pinching at the poles. To understand why, picture the noise being calculated across the 
-surface of the sphere instead of across the 2D plane. When you calculate across the 
+of the pinching at the poles. To understand why, picture the noise being calculated across the
+surface of the sphere instead of across the 2D plane. When you calculate across the
 surface of the sphere you never hit an edge, and hence you never create a seam or
 surface of the sphere you never hit an edge, and hence you never create a seam or
 a pinch point on the pole. The following code converts the ``UVs`` into Cartesion
 a pinch point on the pole. The following code converts the ``UVs`` into Cartesion
 coordinates.
 coordinates.
@@ -216,13 +216,13 @@ Coloring the planet
 
 
 Now to make the planet colors. There are many ways to do this, if you look on `Shadertoy <https://www.shadertoy.com>`_
 Now to make the planet colors. There are many ways to do this, if you look on `Shadertoy <https://www.shadertoy.com>`_
 you will find all kinds of ways of mapping colors to procedural planet terrain. For now
 you will find all kinds of ways of mapping colors to procedural planet terrain. For now
-we will stick with a simple gradient between water and land. 
+we will stick with a simple gradient between water and land.
 
 
 To make a gradient in glsl we use the ``mix`` function. ``mix`` takes two values to interpolate
 To make a gradient in glsl we use the ``mix`` function. ``mix`` takes two values to interpolate
 between and a third parameter to choose how much to interpolate between them, in essence
 between and a third parameter to choose how much to interpolate between them, in essence
 it *mixes* the two values together. In other APIs this function is often called ``lerp``.
 it *mixes* the two values together. In other APIs this function is often called ``lerp``.
 Although, ``lerp`` is typically reserved for mixing two floats together, ``mix`` can take any
 Although, ``lerp`` is typically reserved for mixing two floats together, ``mix`` can take any
-values whether it be floats or vector types. 
+values whether it be floats or vector types.
 
 
 ::
 ::
 
 
@@ -231,7 +231,7 @@ values whether it be floats or vector types.
 The first color is blue for the ocean. The second color is a kind of reddish color (because
 The first color is blue for the ocean. The second color is a kind of reddish color (because
 all alien planets need red terrain). And finally they are mixed together by ``n.x * 0.5 + 0.5``.
 all alien planets need red terrain). And finally they are mixed together by ``n.x * 0.5 + 0.5``.
 ``n.x`` smoothly varies between ``-1`` and ``1``. So we map it into the ``0-1`` range that ``mix`` expects.
 ``n.x`` smoothly varies between ``-1`` and ``1``. So we map it into the ``0-1`` range that ``mix`` expects.
-Now you can see that the colors change between blue and red. 
+Now you can see that the colors change between blue and red.
 
 
 .. image:: img/planet_noise_color.png
 .. image:: img/planet_noise_color.png
 
 
@@ -252,7 +252,7 @@ and it returns ``1`` whenever ``n.x`` is above ``0``.
 
 
 One more thing to make this a little more planet-y. The land shouldn't be so blobby lets make the edges
 One more thing to make this a little more planet-y. The land shouldn't be so blobby lets make the edges
 a little rougher. A trick that is often used in shaders to make rough looking terrain with noise is
 a little rougher. A trick that is often used in shaders to make rough looking terrain with noise is
-to layer levels of noise over one another at various frequencies. We use one layer to make the 
+to layer levels of noise over one another at various frequencies. We use one layer to make the
 overall blobby structure of the continents. Then another layer breaks up the edges a bit, and then
 overall blobby structure of the continents. Then another layer breaks up the edges a bit, and then
 another, and so on. What we will do is calculate ``n`` with four lines of shader code
 another, and so on. What we will do is calculate ``n`` with four lines of shader code
 instead of just one. ``n`` becomes:
 instead of just one. ``n`` becomes:
@@ -277,7 +277,7 @@ Making an ocean
 
 
 One final thing to make this look more like a planet. The ocean and the land reflect light differently.
 One final thing to make this look more like a planet. The ocean and the land reflect light differently.
 So we want the ocean to shine a little more than the land. We can do this by passing a fourth value
 So we want the ocean to shine a little more than the land. We can do this by passing a fourth value
-into the ``alpha`` channel of our output ``COLOR`` and using it as a Roughness map. 
+into the ``alpha`` channel of our output ``COLOR`` and using it as a Roughness map.
 
 
 ::
 ::
 
 
@@ -286,24 +286,24 @@ into the ``alpha`` channel of our output ``COLOR`` and using it as a Roughness m
 This line returns ``0.3`` for water and ``1.0`` for land. This means that the land is going to be quite
 This line returns ``0.3`` for water and ``1.0`` for land. This means that the land is going to be quite
 rough while the water will be quite smooth.
 rough while the water will be quite smooth.
 
 
-And then in the material under the "Metallic" section make sure ``Metallic`` is set to ``0`` and 
-``Specular`` is set to ``1``. The reason for this is the water reflects light really well, but 
+And then in the material under the "Metallic" section make sure ``Metallic`` is set to ``0`` and
+``Specular`` is set to ``1``. The reason for this is the water reflects light really well, but
 isn't metallic. These values are not physically accurate, but they are good enough for this demo.
 isn't metallic. These values are not physically accurate, but they are good enough for this demo.
 
 
-Next under the "Roughness" section set ``Roughness`` to ``1`` and set the roughness texture to a 
-:ref:`Viewport Texture <class_ViewportTexture>` pointing to our planet texture :ref:`Viewport <class_Viewport>`. 
-Finally set the ``Texture Channel`` to ``Alpha``. This instructs the renderer to use the ``alpha`` 
+Next under the "Roughness" section set ``Roughness`` to ``1`` and set the roughness texture to a
+:ref:`Viewport Texture <class_ViewportTexture>` pointing to our planet texture :ref:`Viewport <class_Viewport>`.
+Finally set the ``Texture Channel`` to ``Alpha``. This instructs the renderer to use the ``alpha``
 channel of our output ``COLOR`` as the ``Roughness`` value.
 channel of our output ``COLOR`` as the ``Roughness`` value.
 
 
 .. image:: img/planet_ocean.png
 .. image:: img/planet_ocean.png
 
 
-You'll notice that very little changes except that the planet is no longer reflecting the sky. 
+You'll notice that very little changes except that the planet is no longer reflecting the sky.
 This is happening because by default when something is rendered with an
 This is happening because by default when something is rendered with an
 alpha value it gets drawn as a transparent object over the background. And since the default background
 alpha value it gets drawn as a transparent object over the background. And since the default background
-of the :ref:`Viewport <class_Viewport>` is opaque, the ``alpha`` channel of the 
-:ref:`Viewport Texture <class_ViewportTexture>` is ``1`` resulting in the planet texture being 
-drawn with slightly fainter colors and a ``Roughness`` value of ``1`` everywhere. To correct this we 
-go into the :ref:`Viewport <class_Viewport>` and set "Transparent Bg" to on. Since we are now 
+of the :ref:`Viewport <class_Viewport>` is opaque, the ``alpha`` channel of the
+:ref:`Viewport Texture <class_ViewportTexture>` is ``1`` resulting in the planet texture being
+drawn with slightly fainter colors and a ``Roughness`` value of ``1`` everywhere. To correct this we
+go into the :ref:`Viewport <class_Viewport>` and set "Transparent Bg" to on. Since we are now
 rendering one transparent object on top of another we want to enable ``blend_premul_alpha``:
 rendering one transparent object on top of another we want to enable ``blend_premul_alpha``:
 
 
 ::
 ::
@@ -311,7 +311,7 @@ rendering one transparent object on top of another we want to enable ``blend_pre
     render_mode blend_premul_alpha;
     render_mode blend_premul_alpha;
 
 
 This pre-multiplies the colors by the ``alpha`` value and then blends them correctly together. Typically
 This pre-multiplies the colors by the ``alpha`` value and then blends them correctly together. Typically
-when blending one transparent color on top of another, even if the background has an ``alpha`` of ``0`` (as it 
+when blending one transparent color on top of another, even if the background has an ``alpha`` of ``0`` (as it
 does in this case), you end up with weird color bleed issues. Setting ``blend_premul_alpha`` fixes that.
 does in this case), you end up with weird color bleed issues. Setting ``blend_premul_alpha`` fixes that.
 
 
 Now the planet should look like it is reflecting light on the ocean but not the land. If you haven't done
 Now the planet should look like it is reflecting light on the ocean but not the land. If you haven't done

+ 19 - 19
tutorials/viewports/viewports.rst

@@ -8,30 +8,30 @@ Introduction
 
 
 Think of :ref:`Viewports <class_Viewport>` as a screen that the game is projected onto. In order
 Think of :ref:`Viewports <class_Viewport>` as a screen that the game is projected onto. In order
 to see the game we need to have a surface to draw it on, this surface is
 to see the game we need to have a surface to draw it on, this surface is
-the Root :ref:`Viewport <class_Viewport>`. 
+the Root :ref:`Viewport <class_Viewport>`.
 
 
 .. image:: img/viewportnode.png
 .. image:: img/viewportnode.png
 
 
 
 
 :ref:`Viewports <class_Viewport>` can also be added to the scene so that there
 :ref:`Viewports <class_Viewport>` can also be added to the scene so that there
-are multiple surfaces to draw on. When we are drawing to a :ref:`Viewport <class_Viewport>` 
-that is not the Root we call it a render target. We can access the contents 
-of a render target by accessing its corresponding :ref:`texture <class_ViewportTexture>`. 
+are multiple surfaces to draw on. When we are drawing to a :ref:`Viewport <class_Viewport>`
+that is not the Root we call it a render target. We can access the contents
+of a render target by accessing its corresponding :ref:`texture <class_ViewportTexture>`.
 By using a :ref:`Viewport <class_Viewport>` as a render target
 By using a :ref:`Viewport <class_Viewport>` as a render target
 we can either render multiple scenes simultaneously or we can render to
 we can either render multiple scenes simultaneously or we can render to
-a :ref:`texture <class_ViewportTexture>` which is applied to an object in the scene, for example a dynamic 
+a :ref:`texture <class_ViewportTexture>` which is applied to an object in the scene, for example a dynamic
 skybox.
 skybox.
 
 
-:ref:`Viewports <class_Viewport>` have a variety of use cases including: 
+:ref:`Viewports <class_Viewport>` have a variety of use cases including:
 
 
 - Rendering 3D objects within a 2D game
 - Rendering 3D objects within a 2D game
 - Rendering 2D elements in a 3D game
 - Rendering 2D elements in a 3D game
 - Rendering dynamic textures
 - Rendering dynamic textures
 - Generating procedural textures at runtime
 - Generating procedural textures at runtime
-- Rendering multiple cameras in the same scene 
-  
-What all these use cases have in common is that you are given the ability to 
-draw objects to a texture as if it were another screen and then you can choose 
+- Rendering multiple cameras in the same scene
+
+What all these use cases have in common is that you are given the ability to
+draw objects to a texture as if it were another screen and then you can choose
 what to do with the resulting texture.
 what to do with the resulting texture.
 
 
 Input
 Input
@@ -40,8 +40,8 @@ Input
 :ref:`Viewports <class_Viewport>` are also responsible for delivering properly adjusted and
 :ref:`Viewports <class_Viewport>` are also responsible for delivering properly adjusted and
 scaled input events to all their children nodes. Typically input is received by the
 scaled input events to all their children nodes. Typically input is received by the
 nearest :ref:`Viewport <class_Viewport>` in the tree, but you can set :ref:`Viewports <class_Viewport>` to not receive input by checking
 nearest :ref:`Viewport <class_Viewport>` in the tree, but you can set :ref:`Viewports <class_Viewport>` to not receive input by checking
-'Disable Input' to 'on', this will allow the next nearest :ref:`Viewport <class_Viewport>` in the tree to capture 
-the input. 
+'Disable Input' to 'on', this will allow the next nearest :ref:`Viewport <class_Viewport>` in the tree to capture
+the input.
 
 
 .. image:: img/input.png
 .. image:: img/input.png
 
 
@@ -67,7 +67,7 @@ following hierarchy:
 .. image:: img/cameras.png
 .. image:: img/cameras.png
 
 
 CameraA will display on the Root :ref:`Viewport <class_Viewport>` and it will draw MeshA. CameraB
 CameraA will display on the Root :ref:`Viewport <class_Viewport>` and it will draw MeshA. CameraB
-will be captured by the :ref:`Viewport <class_Viewport>` Node along with MeshB. Even though MeshB is in the scene 
+will be captured by the :ref:`Viewport <class_Viewport>` Node along with MeshB. Even though MeshB is in the scene
 hierarchy, it will still not be drawn to the Root :ref:`Viewport <class_Viewport>`. Similarly MeshA will not
 hierarchy, it will still not be drawn to the Root :ref:`Viewport <class_Viewport>`. Similarly MeshA will not
 be visible from the :ref:`Viewport <class_Viewport>` node because :ref:`Viewport <class_Viewport>` nodes only
 be visible from the :ref:`Viewport <class_Viewport>` node because :ref:`Viewport <class_Viewport>` nodes only
 capture nodes below them in the hierarchy.
 capture nodes below them in the hierarchy.
@@ -83,11 +83,11 @@ or make it the current camera by calling:
 Scale & stretching
 Scale & stretching
 ------------------
 ------------------
 
 
-:ref:`Viewports <class_Viewport>` have a "size" property which represents the size of the :ref:`Viewport <class_Viewport>` 
-in pixels. For :ref:`Viewports <class_Viewport>` which are children of :ref:`ViewportContainers <class_viewportcontainer>`, 
+:ref:`Viewports <class_Viewport>` have a "size" property which represents the size of the :ref:`Viewport <class_Viewport>`
+in pixels. For :ref:`Viewports <class_Viewport>` which are children of :ref:`ViewportContainers <class_viewportcontainer>`,
 these values are overridden, but for all others this sets their resolution.
 these values are overridden, but for all others this sets their resolution.
 
 
-It is also possible to scale the 2D content and make the :ref:`Viewport <class_Viewport>` resolution 
+It is also possible to scale the 2D content and make the :ref:`Viewport <class_Viewport>` resolution
 different than the one specified in size, by calling:
 different than the one specified in size, by calling:
 
 
 ::
 ::
@@ -199,7 +199,7 @@ their albedo.
 
 
 Overdraw draws the meshes semi-transparent with an additive blend so you can see how the meshes overlap.
 Overdraw draws the meshes semi-transparent with an additive blend so you can see how the meshes overlap.
 
 
-.. image:: img/overdraw.png 
+.. image:: img/overdraw.png
 
 
 *The same scene with Debug Draw set to Overdraw*
 *The same scene with Debug Draw set to Overdraw*
 
 
@@ -227,12 +227,12 @@ and then selecting the :ref:`Viewport <class_Viewport>` you want to use.
 
 
 .. image:: img/texturepath.png
 .. image:: img/texturepath.png
 
 
-Every frame the :ref:`Viewport <class_Viewport>`'s texture is cleared away with the default clear color (or a transparent 
+Every frame the :ref:`Viewport <class_Viewport>`'s texture is cleared away with the default clear color (or a transparent
 color if Transparent BG is set to true). This can be changed by setting Clear Mode to Never or Next Frame.
 color if Transparent BG is set to true). This can be changed by setting Clear Mode to Never or Next Frame.
 As the name implies, Never means the texture will never be cleared while next frame will
 As the name implies, Never means the texture will never be cleared while next frame will
 clear the texture on the next frame and then set itself to Never.
 clear the texture on the next frame and then set itself to Never.
 
 
-By default, re-rendering of the :ref:`Viewport <class_Viewport>` happens when the 
+By default, re-rendering of the :ref:`Viewport <class_Viewport>` happens when the
 :ref:`Viewport <class_Viewport>`'s :ref:`ViewportTexture <class_ViewportTexture>` has been drawn in a frame. If visible, it will be
 :ref:`Viewport <class_Viewport>`'s :ref:`ViewportTexture <class_ViewportTexture>` has been drawn in a frame. If visible, it will be
 rendered, otherwise it will not. This behavior can be changed to manual
 rendered, otherwise it will not. This behavior can be changed to manual
 rendering (once), or always render, no matter if visible or not. This flexibility
 rendering (once), or always render, no matter if visible or not. This flexibility

+ 1 - 1
tutorials/vr/vr_primer.rst

@@ -18,7 +18,7 @@ You can use the function :ref:`get_interfaces <class_ARVRServer_get_interfaces>`
 To enable an interface you execute the following code:
 To enable an interface you execute the following code:
 
 
 .. tabs::
 .. tabs::
- .. code-tab:: gdscript GDScript 
+ .. code-tab:: gdscript GDScript
 
 
     var arvr_interface = ARVRServer.find_interface("Native mobile")
     var arvr_interface = ARVRServer.find_interface("Native mobile")
     if arvr_interface and arvr_interface.initialize():
     if arvr_interface and arvr_interface.initialize():