More Godot 4 rename fixes (#6315)

* Spatial -> 3D, Transform, Quaternion

* File -> FileAccess

* Camera -> Camera3D

* Update references to MeshInstance and MultiMeshInstance

* ImmediateGeometry -> ImmediateMesh, misc renames
This commit is contained in:
Max Hilbrunner
2022-10-15 20:54:47 +02:00
committed by GitHub
parent 78526465c8
commit 198393eec7
58 changed files with 243 additions and 241 deletions

View File

@@ -334,3 +334,5 @@ source,destination
/tutorials/viewports/using_viewport_as_texture.html,/tutorials/shaders/using_viewport_as_texture.html
/tutorials/viewports/viewports.html,/tutorials/rendering/viewports.html
/tutorials/physics/using_kinematic_body_2d.html,/tutorials/physics/using_character_body_2d.html
/tutorials/plugins/editor/spatial_gizmos.html,/tutorials/plugins/editor/3d_gizmos.html
/tutorials/3d/procedural_geometry/immediategeometry.html,/tutorials/3d/procedural_geometry/immediatemesh.html
1 source destination
334 /tutorials/viewports/using_viewport_as_texture.html /tutorials/shaders/using_viewport_as_texture.html
335 /tutorials/viewports/viewports.html /tutorials/rendering/viewports.html
336 /tutorials/physics/using_kinematic_body_2d.html /tutorials/physics/using_character_body_2d.html
337 /tutorials/plugins/editor/spatial_gizmos.html /tutorials/plugins/editor/3d_gizmos.html
338 /tutorials/3d/procedural_geometry/immediategeometry.html /tutorials/3d/procedural_geometry/immediatemesh.html

View File

@@ -185,7 +185,7 @@ Procedural geometry series:
- :ref:`doc_arraymesh`
- :ref:`doc_surfacetool`
- :ref:`doc_meshdatatool`
- :ref:`doc_immediategeometry`
- :ref:`doc_immediatemesh`
Optimization
^^^^^^^^^^^^

View File

@@ -21,8 +21,8 @@ Node2D
.. image:: img/Node2D.png
Spatial
-------
Node3D
------
.. image:: img/Spatial.png

View File

@@ -59,11 +59,11 @@ where resource_type is one of:
Below every heading comes zero or more ``key = value`` pairs. The
values can be complex datatypes such as Arrays, Transforms, Colors, and
so on. For example, a spatial node looks like:
so on. For example, a Node3D looks like:
::
[node name="Cube" type="Spatial" parent="."]
[node name="Cube" type="Node3D" parent="."]
transform=Transform( 1.0, 0.0, 0.0 ,0.0, 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0 )
@@ -92,10 +92,10 @@ the path should be ``"."``. Here is an example scene tree
::
[node name="Player" type="Spatial"] ; The scene root
[node name="Arm" parent="." type="Spatial"] ; Parented to the scene root
[node name="Hand" parent="Arm" type="Spatial"]
[node name="Finger" parent="Arm/Hand" type="Spatial"]
[node name="Player" type="Node3D"] ; The scene root
[node name="Arm" parent="." type="Node3D"] ; Parented to the scene root
[node name="Hand" parent="Arm" type="Node3D"]
[node name="Finger" parent="Arm/Hand" type="Node3D"]
Similar to the internal resource, the document for each node is currently
@@ -110,7 +110,7 @@ save a file with that node in it. Some example nodes are:
transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , -4.371138828673793e-08 , 1.0 , -0.0 , -1.0 , -4.371138828673793e-08 ,0.0 ,0.0 ,-0.0 )
[node type="MeshInstance" name="Sphere" parent="SpherePhysics"]
[node type="MeshInstance3D" name="Sphere" parent="SpherePhysics"]
mesh = SubResource(9)
transform = Transform( 1.0 , 0.0 , -0.0 , 0.0 , 1.0 , -0.0 , -0.0 , -0.0 , 1.0 ,0.0 ,0.0 ,-0.0 )
@@ -141,13 +141,13 @@ NodePath
A tree structure is not enough to represent the whole scene. Godot uses a
``NodePath(Path/To/Node)`` structure to refer to another node or attribute of
the node anywhere in the scene tree. For instance, MeshInstance uses
the node anywhere in the scene tree. For instance, MeshInstance3D uses
``NodePath()`` to point to its skeleton. Likewise, Animation tracks use
``NodePath()`` to point to node properties to animate.
::
[node name="mesh" type="MeshInstance" parent="Armature001"]
[node name="mesh" type="MeshInstance3D" parent="Armature001"]
mesh = SubResource(1)
skeleton = NodePath("..:")
@@ -158,7 +158,7 @@ the node anywhere in the scene tree. For instance, MeshInstance uses
[sub_resource id=3 type="Animation"]
...
tracks/0/type = "transform
tracks/0/type = "transform"
tracks/0/path = NodePath("Cube:")
...
@@ -166,7 +166,7 @@ the node anywhere in the scene tree. For instance, MeshInstance uses
Skeleton
~~~~~~~~
The Skeleton node inherits the Spatial node, but also may have a list of bones
The Skeleton node inherits the Node3D node, but also may have a list of bones
described in key-value pairs in the format ``bones/Id/Attribute=Value``. The
bone attributes consist of:
@@ -213,7 +213,7 @@ to a single bone in a Skeleton node. The BoneAttachment has a
``bone_name=NameOfBone`` attribute, and the corresponding bone being the parent has the
BoneAttachment node in its ``bound_children`` list.
An example of one MeshInstance parented to a bone in Skeleton:
An example of one MeshInstance3D parented to a bone in Skeleton:
::
@@ -231,7 +231,7 @@ An example of one MeshInstance parented to a bone in Skeleton:
bone_name = "Bone"
[node name="Cylinder" type="MeshInstance" parent="Armature/BoneAttachment"]
[node name="Cylinder" type="MeshInstance3D" parent="Armature/BoneAttachment"]
mesh = SubResource(1)
transform = Transform(1.0, 0.0, 0.0, 0.0, 1.86265e-09, 1.0, 0.0, -1.0, 0.0, 0.0219986, -0.0343127, 2.25595)
@@ -262,7 +262,7 @@ AnimationPlayer. The root node is stored as
Resources
---------
Resources are components that make up the nodes. For example, a MeshInstance
Resources are components that make up the nodes. For example, a MeshInstance3D
node will have an accompanying ArrayMesh resource. The ArrayMesh resource
may be either internal or external to the TSCN file.

View File

@@ -29,7 +29,7 @@ the jump and squash mechanics.
For now, we're going to create a basic rig for our character's 3D model. This
will allow us to rotate the model later via code while it plays an animation.
Add a *Spatial* node as a child of *Player* and name it *Pivot*. Then, in the
Add a *Node3D* node as a child of *Player* and name it *Pivot*. Then, in the
FileSystem dock, expand the ``art/`` folder by double-clicking it and drag and
drop ``player.glb`` onto the *Pivot* node.

View File

@@ -146,7 +146,7 @@ call its ``normalize()`` method.
if (direction != Vector3.Zero)
{
direction = direction.Normalized();
GetNode<Spatial>("Pivot").LookAt(Translation + direction, Vector3.Up);
GetNode<Node3D>("Pivot").LookAt(Translation + direction, Vector3.Up);
}
}
@@ -305,7 +305,7 @@ Here is the complete ``Player.gd`` code for reference.
if (direction != Vector3.Zero)
{
direction = direction.Normalized();
GetNode<Spatial>("Pivot").LookAt(Translation + direction, Vector3.Up);
GetNode<Node3D>("Pivot").LookAt(Translation + direction, Vector3.Up);
}
// Ground velocity
@@ -346,7 +346,7 @@ Adding a camera
Let's add the camera next. Like we did with our *Player*\ 's *Pivot*, we're
going to create a basic rig. Right-click on the *Main* node again and select
*Add Child Node* this time. Create a new *Position3D*, name it *CameraPivot*,
*Add Child Node* this time. Create a new *Marker3D*, name it *CameraPivot*,
and add a *Camera* node as a child of it. Your scene tree should look like this.
|image3|

View File

@@ -10,7 +10,7 @@ Let's design the monsters themselves in a new scene. The node structure is going
to be similar to the *Player* scene.
Create a scene with, once again, a *CharacterBody3D* node as its root. Name it
*Mob*. Add a *Spatial* node as a child of it, name it *Pivot*. And drag and drop
*Mob*. Add a *Node3D* node as a child of it, name it *Pivot*. And drag and drop
the file ``mob.glb`` from the *FileSystem* dock onto the *Pivot* to add the
monster's 3D model to the scene. You can rename the newly created *mob* node
into *Character*.

View File

@@ -44,7 +44,7 @@ viewport.
Adding placeholder cylinders
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Let's add the placeholder meshes. Add a new *Spatial* node as a child of the
Let's add the placeholder meshes. Add a new *Node3D* node as a child of the
*Main* node and name it *Cylinders*. We'll use it to group the cylinders. As a
child of it, add a *MeshInstance* node.
@@ -101,7 +101,7 @@ last one.
|image12|
In the *Inspector*, expand the *Material* section and assign a *SpatialMaterial*
In the *Inspector*, expand the *Material* section and assign a *StandardMaterial3D*
to slot *0*.
|image13|

View File

@@ -418,7 +418,7 @@ Finally, the longest script, ``Player.gd``.
if (direction != Vector3.Zero)
{
direction = direction.Normalized();
GetNode<Spatial>("Pivot").LookAt(Translation + direction, Vector3.Up);
GetNode<Node3D>("Pivot").LookAt(Translation + direction, Vector3.Up);
}
_velocity.x = direction.x * Speed;

View File

@@ -232,7 +232,7 @@ at the end of ``_physics_process()``.
public override void _PhysicsProcess(float delta)
{
// ...
var pivot = GetNode<Spatial>("Pivot");
var pivot = GetNode<Node3D>("Pivot");
pivot.Rotation = new Vector3(Mathf.Pi / 6f * _velocity.y / JumpImpulse, pivot.Rotation.y, pivot.Rotation.z);
}
@@ -394,7 +394,7 @@ Here's the *Player* script.
if (direction != Vector3.Zero)
{
direction = direction.Normalized();
GetNode<Spatial>("Pivot").LookAt(Translation + direction, Vector3.Up);
GetNode<Node3D>("Pivot").LookAt(Translation + direction, Vector3.Up);
GetNode<AnimationPlayer>("AnimationPlayer").PlaybackSpeed = 4;
}
else
@@ -427,7 +427,7 @@ Here's the *Player* script.
}
}
var pivot = GetNode<Spatial>("Pivot");
var pivot = GetNode<Node3D>("Pivot");
pivot.Rotation = new Vector3(Mathf.Pi / 6f * _velocity.y / JumpImpulse, pivot.Rotation.y, pivot.Rotation.z);
}

View File

@@ -71,7 +71,7 @@ opening the project, you should see an empty editor.
.. image:: img/nodes_and_scenes_01_empty_editor.png
In an empty scene, the Scene dock on the left shows several options to add a
root node quickly. "2D Scene" adds a Node2D node, "3D Scene" adds a Spatial
root node quickly. "2D Scene" adds a Node2D node, "3D Scene" adds a Node3D
node, and "User Interface" adds a Control node. These presets
are here for convenience; they are not mandatory. "Other Node" lets you select any
node to be the root node. In an empty scene, "Other Node" is equivalent to pressing

View File

@@ -152,7 +152,7 @@ cover the scene with the volume as you do with ``GIProbe``:
Setting up meshes
~~~~~~~~~~~~~~~~~
For a **MeshInstance** node to take part in the baking process, it needs to have
For a **MeshInstance3D** node to take part in the baking process, it needs to have
the **Use in Baked Light** property enabled.
.. image:: img/baked_light_use.png

View File

@@ -126,7 +126,7 @@ Our level will contain these objects:
- a desk,
- a bookshelf.
Create a scene with a Spatial node as root node.
Create a scene with a Node3D node as root node.
.. tip:: The default lighting of the environment doesn't provide clear shading
at some angles. Change the display mode using **Display Overdraw** in
@@ -182,7 +182,7 @@ spheres will cut a hole into the mattress.
.. image:: img/csg_pillow_hole.png
Try to re-parent the ``pillow`` node to the root ``Spatial`` node; the hole will
Try to re-parent the ``pillow`` node to the root ``Node3D`` node; the hole will
disappear.
.. note:: This is to illustrate the effect of CSG processing order.
@@ -271,14 +271,14 @@ There are two ways to apply a material to a CSG node:
To apply triplanar mapping to a CSG node, select it, go to the Inspector, click
the **[empty]** text next to **Material Override** (or **Material** for
individual CSG nodes). Choose **New SpatialMaterial**. Click the newly created
individual CSG nodes). Choose **New StandardMaterial3D**. Click the newly created
material's icon to edit it. Unfold the **Albedo** section and load a texture
into the **Texture** property. Now, unfold the **Uv1** section and check
**Triplanar**. You can change the texture offset and scale on each axis by
playing with the **Scale** and **Offset** properties just above. Higher values
in the **Scale** property will cause the texture to repeat more often.
.. tip:: You can copy a SpatialMaterial to reuse it across CSG nodes. To do so,
.. tip:: You can copy a StandardMaterial3D to reuse it across CSG nodes. To do so,
click the dropdown arrow next to a material property in the Inspector
and choose **Copy**. To paste it, select the node you'd like to apply
the material onto, click the dropdown arrow next to its material

View File

@@ -16,19 +16,19 @@ In 3D, math is a little more complex than in 2D, so also checking the
developers, not mathematicians or engineers) will help pave the way for you
to develop 3D games efficiently.
Spatial node
~~~~~~~~~~~~
Node3D node
~~~~~~~~~~~
:ref:`Node2D <class_Node2D>` is the base node for 2D.
:ref:`Control <class_Control>` is the base node for everything GUI.
Following this reasoning, the 3D engine uses the :ref:`Spatial <class_Spatial>`
Following this reasoning, the 3D engine uses the :ref:`Node3D <class_Node3D>`
node for everything 3D.
.. image:: img/tuto_3d1.png
Spatial nodes have a local transform, which is relative to the parent
Node3Ds have a local transform, which is relative to the parent
node (as long as the parent node is also of **or inherits from** the type
Spatial). This transform can be accessed as a 4×3
Node3D). This transform can be accessed as a 4×3
:ref:`Transform3D <class_Transform3D>`, or as 3 :ref:`Vector3 <class_Vector3>`
members representing location, Euler rotation (X, Y and Z angles) and
scale.
@@ -56,7 +56,7 @@ entire scenes (exactly as they look in the DCC), including animation,
skeletal rigs, blend shapes, etc.
The second pipeline is by importing simple .OBJ files as mesh resources,
which can be then put inside a :ref:`MeshInstance <class_MeshInstance>`
which can be then put inside a :ref:`MeshInstance3D <class_MeshInstance3D>`
node for display.
Generated geometry
@@ -78,7 +78,7 @@ Immediate geometry
If, instead, you need to generate simple geometry that
will be updated often, Godot provides a special node,
:ref:`ImmediateGeometry <class_ImmediateGeometry>`,
:ref:`ImmediateMesh <class_ImmediateMesh>`,
which provides an OpenGL 1.x style immediate-mode API to create points,
lines, triangles, etc.
@@ -110,7 +110,7 @@ Environments can also be overridden in the Camera.
~~~~~~~~~~~
Editing 3D scenes is done in the 3D tab. This tab can be selected
manually, but it will be automatically enabled when a Spatial node is
manually, but it will be automatically enabled when a Node3D node is
selected.
.. image:: img/tuto_3d3.png
@@ -193,7 +193,7 @@ Cameras
-------
No matter how many objects are placed in the 3D space, nothing will be
displayed unless a :ref:`Camera <class_Camera>` is
displayed unless a :ref:`Camera3D <class_Camera3D>` is
also added to the scene. Cameras can work in either orthogonal or
perspective projections:

View File

@@ -1,9 +1,9 @@
.. _doc_immediategeometry:
.. _doc_immediatemesh:
Using ImmediateGeometry
=======================
Using ImmediateMesh
===================
Unlike the SurfaceTool or ArrayMesh, :ref:`ImmediateGeometry <class_ImmediateGeometry>` is an actual
Unlike the SurfaceTool or ArrayMesh, :ref:`ImmediateMesh <class_ImmediateMesh>` is an actual
node. Being a node makes it quick to add to a scene and get visual output. It uses an OpenGL 1.x-style
API like SurfaceTool, but it's actually designed to create meshes on the fly.
@@ -40,7 +40,7 @@ The example code below draws a single triangle.
.. tabs::
.. code-tab:: gdscript GDScript
extends ImmediateGeometry
extends ImmediateMesh
func _process(_delta):
# Clean up before drawing.

View File

@@ -14,7 +14,7 @@ it is best to understand each one and how it can be useful in a given situation.
arraymesh
meshdatatool
surfacetool
immediategeometry
immediatemesh
.. note::
@@ -106,19 +106,19 @@ The SurfaceTool allows the creation of Meshes using an OpenGL 1.x immediate mode
For more information about the SurfaceTool, please see the :ref:`SurfaceTool tutorial <doc_surfacetool>`.
ImmediateGeometry
^^^^^^^^^^^^^^^^^
ImmediateMesh
^^^^^^^^^^^^^
ImmediateGeometry is a node that uses an immediate mode style interface (like SurfaceTool) to draw objects. The
difference between ImmediateGeometry and the SurfaceTool is that ImmediateGeometry is a node itself that can be
ImmediateMesh is a node that uses an immediate mode style interface (like SurfaceTool) to draw objects. The
difference between ImmediateMesh and the SurfaceTool is that ImmediateMesh is a node itself that can be
added to the scene tree and is drawn directly from the code, while The SurfaceTool generates a Mesh that needs to be added to
a MeshInstance3D to be seen.
ImmediateGeometry is useful for prototyping because of its straightforward API, but it is slow because the geometry
ImmediateMesh is useful for prototyping because of its straightforward API, but it is slow because the geometry
is rebuilt every frame. It is most useful for adding simple geometry for visual debugging (e.g. by drawing lines to
visualize physics raycasts etc.).
For more information about ImmediateGeometry, please see the :ref:`ImmediateGeometry tutorial <doc_immediategeometry>`.
For more information about ImmediateMesh, please see the :ref:`ImmediateMesh tutorial <doc_immediatemesh>`.
Which one should I use?
-----------------------
@@ -130,7 +130,7 @@ Both SurfaceTool and ArrayMesh are excellent for generating static geometry (mes
Using an ArrayMesh is slightly faster than using a SurfaceTool, but the API is a little more challenging.
Additionally, SurfaceTool has a few quality of life methods such as ``generate_normals()`` and ``index()``.
ImmediateGeometry regenerates the mesh every frame, so it is much slower than ArrayMesh or SurfaceTool. However, if you
ImmediateMesh regenerates the mesh every frame, so it is much slower than ArrayMesh or SurfaceTool. However, if you
need the geometry to change every frame anyway, it provides a much easier interface that may even be a little faster than generating
an ArrayMesh every frame.

View File

@@ -4,7 +4,7 @@ Using the SurfaceTool
=====================
The :ref:`SurfaceTool <class_surfacetool>` provides a useful interface for constructing geometry.
The interface is similar to the :ref:`ImmediateGeometry <class_immediategeometry>` node. You
The interface is similar to the :ref:`ImmediateMesh <class_ImmediateMesh>` node. You
set each per-vertex attribute (e.g. normal, uv, color) and then when you add a vertex it
captures the attributes.

View File

@@ -15,7 +15,7 @@ This tutorial explains the parameters present in both materials.
There are 4 ways to add these materials to an object. A material can be added in
the *Material* property of the mesh. It can be added in the *Material* property of
the node using the mesh (such as a MeshInstance node), the *Material Override* property
the node using the mesh (such as a MeshInstance3D node), the *Material Override* property
of the node using the mesh, and the *Material Overlay*.
.. image:: img/add_material.png
@@ -176,7 +176,7 @@ the object. The default is *Burley*. Other modes are also available:
(via roughness). Works well for clay-like materials and some types of cloth.
* **Toon:** Provides a hard cut for lighting, with smoothing affected by roughness.
It is recommended you disable sky contribution from your environment's
ambient light settings or disable ambient light in the spatial material
ambient light settings or disable ambient light in the StandardMaterial3D
to achieve a better effect.
.. image:: img/spatial_material6.png

View File

@@ -33,8 +33,8 @@ scene to see an example of how to set up the mesh library.
.. image:: img/gridmap_meshlibrary1.png
As you can see, this scene has a :ref:`class_Spatial` node as its root, and
a number of :ref:`class_MeshInstance` node children.
As you can see, this scene has a :ref:`class_Node3D` node as its root, and
a number of :ref:`class_MeshInstance3D` node children.
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.
@@ -69,7 +69,7 @@ Like all mesh instances, MeshLibrary items can be assigned a :ref:`class_Navigat
resource, which can be created manually, or baked as described below.
To create the NavigationMesh from a MeshLibrary scene export, place a
:ref:`class_NavigationRegion3D` child node below the main MeshInstance for the GridMap
:ref:`class_NavigationRegion3D` child node below the main MeshInstance3D for the GridMap
item. Add a valid NavigationMesh resource to the NavigationRegion3D and some source
geometry nodes below and bake the NavigationMesh.

View File

@@ -1,29 +1,29 @@
.. _doc_using_multi_mesh_instance:
Using MultiMeshInstance
-----------------------
Using MultiMeshInstance3D
-------------------------
Introduction
~~~~~~~~~~~~
In a normal scenario, you would use a :ref:`MeshInstance <class_MeshInstance>`
In a normal scenario, you would use a :ref:`MeshInstance3D <class_MeshInstance3D>`
node to display a 3D mesh like a human model for the main character, but in some
cases, you would like to create multiple instances of the same mesh in a scene.
You *could* duplicate the same node multiple times and adjust the transforms
manually. This may be a tedious process and the result may look mechanical.
Also, this method is not conducive to rapid iterations.
:ref:`MultiMeshInstance <class_MultiMeshInstance>` is one of the possible
:ref:`MultiMeshInstance3D <class_MultiMeshInstance3D>` is one of the possible
solutions to this problem.
MultiMeshInstance, as the name suggests, creates multiple copies of a
MultiMeshInstance3D, as the name suggests, creates multiple copies of a
MeshInstance over a surface of a specific mesh. An example would be having a
tree mesh populate a landscape mesh with trees of random scales and orientations.
Setting up the nodes
~~~~~~~~~~~~~~~~~~~~
The basic setup requires three nodes: the MultiMeshInstance node
and two MeshInstance nodes.
The basic setup requires three nodes: the MultiMeshInstance3D node
and two MeshInstance3D nodes.
One node is used as the target, the surface mesh that you want to place multiple meshes
on. In the tree example, this would be the landscape.
@@ -31,14 +31,14 @@ on. In the tree example, this would be the landscape.
The other node is used as the source, the mesh that you want to have duplicated.
In the tree case, this would be the tree itself.
In our example, we would use a :ref:`Spatial <class_Spatial>` node as the root node of
In our example, we would use a :ref:`Node3D <class_Node3D>` node as the root node of
the scene. Your scene tree would look like this:
.. image:: img/multimesh_scene_tree.png
.. note:: For simplicity's sake, this tutorial uses built-in primitives.
Now you have everything ready. Select the MultiMeshInstance node and look at the
Now you have everything ready. Select the MultiMeshInstance3D node and look at the
toolbar, you should see an extra button called ``MultiMesh`` next to ``View``.
Click it and select *Populate surface* in the dropdown menu. A new window titled
*Populate MultiMesh* will pop up.

View File

@@ -79,14 +79,14 @@ There are a few reasons this may happen:
Say no to Euler angles
======================
The result of all this is that you should **not use** the ``rotation`` property of :ref:`class_Spatial` nodes in Godot for games. It's there to be used mainly in the editor, for coherence with the 2D engine, and for simple rotations (generally just one axis, or even two in limited cases). As much as you may be tempted, don't use it.
The result of all this is that you should **not use** the ``rotation`` property of :ref:`class_Node3D` nodes in Godot for games. It's there to be used mainly in the editor, for coherence with the 2D engine, and for simple rotations (generally just one axis, or even two in limited cases). As much as you may be tempted, don't use it.
Instead, there is a better way to solve your rotation problems.
Introducing transforms
----------------------
Godot uses the :ref:`class_Transform` datatype for orientations. Each :ref:`class_Spatial` node contains a ``transform`` property which is relative to the parent's transform, if the parent is a Spatial-derived type.
Godot uses the :ref:`class_Transform3D` datatype for orientations. Each :ref:`class_Node3D` node contains a ``transform`` property which is relative to the parent's transform, if the parent is a Node3D-derived type.
It is also possible to access the world coordinate transform via the ``global_transform`` property.
@@ -165,7 +165,7 @@ It is possible to rotate a transform, either by multiplying its basis by another
// shortened
transform.basis = transform.basis.Rotated(axis, rotationAmount);
A method in Spatial simplifies this:
A method in Node3D simplifies this:
.. tabs::
.. code-tab:: gdscript GDScript
@@ -217,7 +217,7 @@ There are two different ways to handle this. The first is to *orthonormalize* th
This will make all axes have ``1.0`` length again and be ``90`` degrees from each other. However, any scale applied to the transform will be lost.
It is recommended you not scale nodes that are going to be manipulated; scale their children nodes instead (such as MeshInstance). If you absolutely must scale the node, then re-apply it at the end:
It is recommended you not scale nodes that are going to be manipulated; scale their children nodes instead (such as MeshInstance3D). If you absolutely must scale the node, then re-apply it at the end:
.. tabs::
.. code-tab:: gdscript GDScript
@@ -367,8 +367,8 @@ Converting a rotation to quaternion is straightforward.
.. code-tab:: gdscript GDScript
# Convert basis to quaternion, keep in mind scale is lost
var a = Quat(transform.basis)
var b = Quat(transform2.basis)
var a = Quaternion(transform.basis)
var b = Quaternion(transform2.basis)
# Interpolate using spherical-linear interpolation (SLERP).
var c = a.slerp(b,0.5) # find halfway point between a and b
# Apply back
@@ -377,14 +377,14 @@ Converting a rotation to quaternion is straightforward.
.. code-tab:: csharp
// Convert basis to quaternion, keep in mind scale is lost
var a = transform.basis.Quat();
var b = transform2.basis.Quat();
var a = transform.basis.Quaternion();
var b = transform2.basis.Quaternion();
// Interpolate using spherical-linear interpolation (SLERP).
var c = a.Slerp(b, 0.5f); // find halfway point between a and b
// Apply back
transform.basis = new Basis(c);
The :ref:`class_Quat` type reference has more information on the datatype (it
The :ref:`class_Quaternion` type reference has more information on the datatype (it
can also do transform accumulation, transform points, etc., though this is used
less often). If you interpolate or apply operations to quaternions many times,
keep in mind they need to be eventually normalized. Otherwise, they will also

View File

@@ -193,7 +193,7 @@ node with its parent. And there's currently no child of the hand node.
With this knowledge let's try again.
The first step is creating an endpoint node. Any kind of node will do,
but :ref:`Position2D <class_Position2D>` is preferred because it's
but :ref:`Marker2D <class_Marker2D>` is preferred because it's
visible in the editor. The endpoint node will ensure that the last bone
has orientation.

View File

@@ -52,7 +52,7 @@ difficulties in implementation, which are:
Sometimes materials may not be valid for exporting (e.g. has some unsupported node) or it
is using Blender Internal Engine, only the diffuse color and a few flags (e.g. unshaded) are
exported and form a Spatial Material.
exported and form a StandardMaterial3D.
Generate external materials

View File

@@ -8,7 +8,7 @@ physics tab:
.. important::
By default, a single Blender object with rigid body enabled will export as
three nodes: a PhysicsBody, a CollisionShape, and a MeshInstance.
three nodes: a PhysicsBody, a CollisionShape, and a MeshInstance3D.
Body type
---------

View File

@@ -20,11 +20,11 @@ and keep the imported resources hidden in a ``res://.import`` folder.
This means that when trying to access imported assets through code you
need to use the :ref:`Resource Loader<class_ResourceLoader>` as it will
automatically take into account where the internal files are saved. If you
try and access an imported asset using the :ref:`File <class_File>` class
try and access an imported asset using the :ref:`FileAccess <class_FileAccess>` class
it will work in the editor, but break in the exported project.
However, the :ref:`Resource Loader<class_ResourceLoader>` cannot access
non imported files, only the :ref:`File <class_File>` class can.
non imported files, only the :ref:`FileAccess <class_FileAccess>` class can.
Changing import parameters
--------------------------

View File

@@ -144,7 +144,7 @@ Nodes
Root Type
^^^^^^^^^
By default, the type of the root node in imported scenes is "Spatial", but this can be modified.
By default, the type of the root node in imported scenes is "Node3D", but this can be modified.
Root Name
^^^^^^^^^
@@ -504,7 +504,7 @@ A mesh node with the ``-wheel`` suffix will be imported as a child to a
Rigid Body (-rigid)
~~~~~~~~~~~~~~~~~~~
A mesh node with the ``-rigid`` suffix will be imported as a :ref:`class_RigidBody`.
A mesh node with the ``-rigid`` suffix will be imported as a :ref:`class_RigidBody3D`.
Animation loop (-loop, -cycle)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@@ -175,7 +175,7 @@ Reverb
Reverb simulates rooms of different sizes. It has adjustable parameters that can
be tweaked to obtain the sound of a specific room. Reverb is commonly outputted
from :ref:`Areas <class_Area>`
from :ref:`Area3Ds <class_Area3D>`
(see :ref:`Reverb buses <doc_audio_streams_reverb_buses>`), or to apply
a "chamber" feel to all sounds.

View File

@@ -38,7 +38,7 @@ your project's features.
further references to themselves exist. These are useful in the majority of
cases where one needs data in a custom class.
- **Example:** See the :ref:`File <class_File>` object. It functions
- **Example:** See the :ref:`FileAccess <class_FileAccess>` object. It functions
just like a regular Object except that one need not delete it themselves.
- **Advantages:** same as the Object.

View File

@@ -274,7 +274,7 @@ of Main. In addition, one will need a primary GUI for their game that manages
the various menus and widgets the project needs.
- Node "Main" (main.gd)
- Node2D/Spatial "World" (game_world.gd)
- Node2D/Node3D "World" (game_world.gd)
- Control "GUI" (gui.gd)
When changing levels, one can then swap out the children of the "World" node.
@@ -319,7 +319,7 @@ own place in the hierarchy as a sibling or some other relation.
In some cases, one needs these separated nodes to *also* position themselves
relative to each other. One can use the
:ref:`RemoteTransform <class_RemoteTransform>` /
:ref:`RemoteTransform <class_RemoteTransform3D>` /
:ref:`RemoteTransform2D <class_RemoteTransform2D>` nodes for this purpose.
They will allow a target node to conditionally inherit selected transform
elements from the Remote\* node. To assign the ``target``
@@ -372,7 +372,7 @@ own place in the hierarchy as a sibling or some other relation.
information to their children.
2. The **imperative** solution: Use the ``set_as_toplevel`` setter for the
:ref:`CanvasItem <class_CanvasItem_method_set_as_toplevel>` or
:ref:`Spatial <class_Spatial_method_set_as_toplevel>` node. This will make
:ref:`Node3D <class_Node3D_method_set_as_toplevel>` node. This will make
the node ignore its inherited transform.
.. note::

View File

@@ -89,12 +89,12 @@ received input, in order:
:ref:`Node.set_process_unhandled_input() <class_Node_method_set_process_unhandled_input>`).
If any function consumes the event, it can call :ref:`SceneTree.set_input_as_handled() <class_SceneTree_method_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.
4. If no one wanted the event so far, and a :ref:`Camera <class_Camera>` is assigned
4. If no one wanted the event so far, and a :ref:`Camera3D <class_Camera3D>` is assigned
to the Viewport with :ref:`Object Picking <class_viewport_property_physics_object_picking>` turned on, a ray to the physics world (in the ray direction from
the click) will be cast. (For the root viewport, this can also be enabled in :ref:`Project Settings <class_ProjectSettings_property_physics/common/enable_object_picking>`) If this ray hits an object, it will call the
:ref:`CollisionObject._input_event() <class_CollisionObject_method__input_event>` function in the relevant
physics object (bodies receive this callback by default, but areas do
not. This can be configured through :ref:`Area <class_Area>` properties).
not. This can be configured through :ref:`Area3D <class_Area3D>` properties).
5. Finally, if the event was unhandled, it will be passed to the next
Viewport in the tree, otherwise it will be ignored.

View File

@@ -8,7 +8,7 @@ Introduction
Godot has a serialization API based on Variant. It's used for
converting data types to an array of bytes efficiently. This API is used
in the functions ``get_var`` and ``store_var`` of :ref:`class_File`
in the functions ``get_var`` and ``store_var`` of :ref:`class_FileAccess`
as well as the packet APIs for :ref:`class_PacketPeer`. This format
is *not* used for binary scenes and resources.
@@ -58,13 +58,13 @@ two bytes contain flags::
+--------+--------------------------+
| 9 | plane |
+--------+--------------------------+
| 10 | quat |
| 10 | quaternion |
+--------+--------------------------+
| 11 | aabb |
+--------+--------------------------+
| 12 | basis |
+--------+--------------------------+
| 13 | transform |
| 13 | transform3d |
+--------+--------------------------+
| 14 | color |
+--------+--------------------------+
@@ -244,8 +244,8 @@ This field is padded to 4 bytes.
| 16 | 4 | Float | Distance |
+----------+-------+---------+---------------+
10: :ref:`Quat<class_quat>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^
10: :ref:`Quaternion<class_quaternion>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+----------+-------+---------+---------------+
| Offset | Len | Type | Description |
@@ -303,8 +303,8 @@ This field is padded to 4 bytes.
| 36 | 4 | Float | The Z component of the Z column vector, accessed via [2][2] |
+----------+-------+---------+---------------------------------------------------------------+
13: :ref:`Transform<class_transform>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
13: :ref:`Transform3D<class_transform3d>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+----------+-------+---------+---------------------------------------------------------------+
| Offset | Len | Type | Description |

View File

@@ -341,7 +341,7 @@ Here are some important gotchas to know about when using JSON.
JSON only offers a limited set of data types. If you have data types
that JSON doesn't have, you will need to translate your data to and
from types that JSON can handle. For example, some important types that JSON
can't parse are: ``Vector2``, ``Vector3``, ``Color``, ``Rect2``, and ``Quat``.
can't parse are: ``Vector2``, ``Vector3``, ``Color``, ``Rect2``, and ``Quaternion``.
* **Custom logic needed for encoding/decoding:**
If you have any custom classes that you want to store with JSON, you will
need to write your own logic for encoding and decoding those classes.
@@ -351,7 +351,7 @@ Binary serialization
:ref:`Binary serialization<doc_binary_serialization_api>` is an alternative
approach for storing game state, and you can use it with the functions
``get_var`` and ``store_var`` of :ref:`class_File`.
``get_var`` and ``store_var`` of :ref:`class_FileAccess`.
* Binary serialization should produce smaller files than JSON.
* Binary serialization can handle most common data types.

View File

@@ -53,8 +53,8 @@ Here is example pseudo-code for going from point A to B using interpolation:
{
_t += delta * 0.4f;
Position2D a = GetNode<Position2D>("A");
Position2D b = GetNode<Position2D>("B");
Marker2D a = GetNode<Marker2D>("A");
Marker2D b = GetNode<Marker2D>("B");
Sprite2D sprite = GetNode<Sprite2D>("Sprite2D");
sprite.Position = a.Position.Lerp(b.Position, _t);
@@ -94,8 +94,8 @@ Using the following pseudocode:
{
_t += delta;
Position3D p1 = GetNode<Position3D>("Position1");
Position3D p2 = GetNode<Position3D>("Position2");
Marker3D p1 = GetNode<Marker3D>("Position1");
Marker3D p2 = GetNode<Marker3D>("Position2");
CSGMesh3D monkey = GetNode<CSGMesh3D>("Monkey");
monkey.Transform = p1.Transform.InterpolateWith(p2.Transform, _t);

View File

@@ -4,7 +4,7 @@
3D Navigation Overview
======================
Godot provides multiple objects, classes and servers to facilitate grid-based or mesh-based navigation and pathfinding for 2D and 3D games.
Godot provides multiple objects, classes and servers to facilitate grid-based or mesh-based navigation and pathfinding for 2D and 3D games.
The following section provides a quick overview over all available navigation related objects in Godot for 3D scenes and their primary use.
Godot provides the following objects and classes for 3D navigation:
@@ -78,9 +78,9 @@ a NavigationAgent3D for path movement.
.. image:: img/nav_3d_min_setup_step1.png
3.) Add a new MeshInstance node as a child of the region node
3.) Add a new MeshInstance3D node as a child of the region node
4.) Select the meshinstance node and add a new PlaneMesh and increase the xy size to 10.
4.) Select the MeshInstance3D node and add a new PlaneMesh and increase the xy size to 10.
5.) Select the region node again and press the "Bake Navmesh" button on the top bar

View File

@@ -53,7 +53,7 @@ efficient for millions of objects, but for a few thousands, GDScript should be f
.. tabs::
.. code-tab:: gdscript GDScript
extends MultiMeshInstance
extends MultiMeshInstance3D
func _ready():
@@ -77,7 +77,7 @@ efficient for millions of objects, but for a few thousands, GDScript should be f
using Godot;
using System;
public class YourClassName : MultiMeshInstance
public class YourClassName : MultiMeshInstance3D
{
public override void _Ready()
{

View File

@@ -66,7 +66,7 @@ For nodes, there are many functions available:
* For Viewport, the :ref:`Viewport.get_viewport_rid() <class_Viewport_method_get_viewport_rid>`
method will return the viewport RID in the server.
* For 3D, the :ref:`World3D <class_World3D>` resource (obtainable in the :ref:`Viewport <class_Viewport>`
and :ref:`Spatial <class_Spatial>` nodes)
and :ref:`Node3D <class_Node3D>` nodes)
contains functions to get the *RenderingServer Scenario*, and the *PhysicsServer Space*. This
allows creating 3D objects directly with the server API and using them.
* For 2D, the :ref:`World2D <class_World2D>` resource (obtainable in the :ref:`Viewport <class_Viewport>`
@@ -132,7 +132,7 @@ The 3D APIs are different from the 2D ones, so the instantiation API must be use
.. tabs::
.. code-tab:: gdscript GDScript
extends Spatial
extends Node3D
# RenderingServer expects references to be kept around.
@@ -193,7 +193,7 @@ and moves a :ref:`CanvasItem <class_CanvasItem>` when the body moves.
Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)
The 3D version should be very similar, as 2D and 3D physics servers are identical (using
:ref:`RigidBody <class_RigidBody>` and :ref:`PhysicsServer <class_PhysicsServer>` respectively).
:ref:`RigidBody3D <class_RigidBody3D>` and :ref:`PhysicsServer <class_PhysicsServer>` respectively).
Getting data from the servers
-----------------------------

View File

@@ -1,14 +1,14 @@
.. _doc_animating_thousands_of_fish:
Animating thousands of fish with MultiMeshInstance
==================================================
Animating thousands of fish with MultiMeshInstance3D
====================================================
This tutorial explores a technique used in the game `ABZU <https://www.gdcvault.com/play/1024409/Creating-the-Art-of-ABZ>`_
for rendering and animating thousands of fish using vertex animation and
static mesh instancing.
In Godot, this can be accomplished with a custom :ref:`Shader <class_Shader>` and
a :ref:`MultiMeshInstance <class_MultiMeshInstance>`. Using the following technique you
a :ref:`MultiMeshInstance3D <class_MultiMeshInstance3D>`. Using the following technique you
can render thousands of animated objects, even on low end hardware.
We will start by animating one fish. Then, we will see how to extend that animation to
@@ -17,7 +17,7 @@ thousands of fish.
Animating one Fish
------------------
We will start with a single fish. Load your fish model into a :ref:`MeshInstance <class_MeshInstance>`
We will start with a single fish. Load your fish model into a :ref:`MeshInstance3D <class_MeshInstance3D>`
and add a new :ref:`ShaderMaterial <class_ShaderMaterial>`.
Here is the fish we will be using for the example images, you can use any fish model you like.
@@ -181,13 +181,13 @@ find that you can create a wide variety of swim styles using these four motions.
Making a school of fish
-----------------------
Godot makes it easy to render thousands of the same object using a MultiMeshInstance node.
Godot makes it easy to render thousands of the same object using a MultiMeshInstance3D node.
A MultiMeshInstance node is created and used the same way you would make a MeshInstance node.
For this tutorial, we will name the MultiMeshInstance node ``School``, because it will contain
A MultiMeshInstance3D node is created and used the same way you would make a MeshInstance3D node.
For this tutorial, we will name the MultiMeshInstance3D node ``School``, because it will contain
a school of fish.
Once you have a MultiMeshInstance add a :ref:`MultiMesh <class_MultiMesh>`, and to that
Once you have a MultiMeshInstance3D add a :ref:`MultiMesh <class_MultiMesh>`, and to that
MultiMesh add your :ref:`Mesh <class_Mesh>` with the shader from above.
MultiMeshes draw your Mesh with three additional per-instance properties: Transform (rotation,
@@ -212,7 +212,7 @@ Now, set ``instance_count`` to the number of fish you want to have.
Next we need to set the per-instance transforms.
There are two ways to set per-instance transforms for MultiMeshes. The first is entirely in editor
and is described in the :ref:`MultiMeshInstance tutorial <doc_using_multi_mesh_instance>`.
and is described in the :ref:`MultiMeshInstance3D tutorial <doc_using_multi_mesh_instance>`.
The second is to loop over all the instances and set their transforms in code. Below, we use GDScript
to loop over all the instances and set their transform to a random position.
@@ -225,7 +225,7 @@ to loop over all the instances and set their transform to a random position.
$School.multimesh.set_instance_transform(i, position)
Running this script will place the fish in random positions in a box around the position of the
MultiMeshInstance.
MultiMeshInstance3D.
.. note:: If performance is an issue for you, try running the scene with GLES2 or with fewer fish.
@@ -268,7 +268,7 @@ custom value.
One problem that you will run into at this point is that the fish are animated, but they are not
moving. You can move them by updating the per-instance transform for each fish every frame. Although
doing so will be faster than moving thousands of MeshInstances per frame, it'll still likely be
doing so will be faster than moving thousands of MeshInstance3Ds per frame, it'll still likely be
slow.
In the next tutorial we will cover how to use :ref:`GPUParticles3D <class_GPUParticles3D>` to take advantage

View File

@@ -3,7 +3,7 @@
Controlling thousands of fish with Particles
============================================
The problem with :ref:`MeshInstances <class_MeshInstance>` is that it is expensive to
The problem with :ref:`MeshInstance3D <class_MeshInstance3D>` is that it is expensive to
update their transform array. It is great for placing many static objects around the
scene. But it is still difficult to move the objects around the scene.
@@ -11,7 +11,7 @@ To make each instance move in an interesting way, we will use a
:ref:`GPUParticles3D <class_GPUParticles3D>` node. Particles take advantage of GPU acceleration
by computing and setting the per-instance information in a :ref:`Shader <class_Shader>`.
.. note:: Particles are not available in GLES2, instead use :ref:`CPUParticles <class_CPUParticles>`,
.. note:: Particles are not available in GLES2, instead use :ref:`CPUParticles3D <class_CPUParticles3D>`,
which do the same thing as Particles, but do not benefit from GPU acceleration.
First create a Particles node. Then, under "Draw Passes" set the Particle's "Draw Pass 1" to your
@@ -52,7 +52,7 @@ These functions come from the default :ref:`ParticleProcessMaterial <class_Parti
They are used to generate a random number from each particle's ``RANDOM_SEED``.
A unique thing about particle shaders is that some built-in variables are saved across frames.
``TRANSFORM``, ``COLOR``, and ``CUSTOM`` can all be accessed in the Spatial shader of the mesh, and
``TRANSFORM``, ``COLOR``, and ``CUSTOM`` can all be accessed in the shader of the mesh, and
also in the particle shader the next time it is run.
Next, setup your ``vertex`` function. Particles shaders only contain a vertex function

View File

@@ -58,7 +58,7 @@ of convex shapes. For large and complex objects such as a whole level, we
recommend using concave shapes instead.
You can generate one or several convex collision shapes from the editor by
selecting a MeshInstance and using the **Mesh** menu at the top of the 3D
selecting a MeshInstance3D and using the **Mesh** menu at the top of the 3D
viewport. The editor exposes two generation modes:
- **Create Single Convex Collision Sibling** uses the Quickhull algorithm. It
@@ -97,7 +97,7 @@ have an actual "volume". You can place objects both *outside* of the shape as
well as *inside*.
You can generate a concave collision shape from the editor by selecting a
MeshInstance and using the **Mesh** menu at the top of the 3D viewport. The
MeshInstance3D and using the **Mesh** menu at the top of the 3D viewport. The
editor exposes two options:
- **Create Trimesh Static Body** is a convenient option. It creates a StaticBody

View File

@@ -28,7 +28,7 @@ In the physics world, Godot stores all the low level collision and
physics information in a *space*. The current 2d space (for 2D Physics)
can be obtained by accessing
:ref:`CanvasItem.get_world_2d().space <class_CanvasItem_method_get_world_2d>`.
For 3D, it's :ref:`Spatial.get_world().space <class_Spatial_method_get_world>`.
For 3D, it's :ref:`Node3D.get_world().space <class_Node3D_method_get_world>`.
The resulting space :ref:`RID <class_RID>` can be used in
:ref:`PhysicsServer <class_PhysicsServer>` and
@@ -232,8 +232,8 @@ picking. There is not much need to do this because
has an "input_event" signal that will let you know when it was clicked,
but in case there is any desire to do it manually, here's how.
To cast a ray from the screen, you need a :ref:`Camera <class_Camera>`
node. A ``Camera`` can be in two projection modes: perspective and
To cast a ray from the screen, you need a :ref:`Camera3D <class_Camera3D>`
node. A ``Camera3D`` can be in two projection modes: perspective and
orthogonal. Because of this, both the ray origin and direction must be
obtained. This is because ``origin`` changes in orthogonal mode, while
``normal`` changes in perspective mode:
@@ -249,9 +249,9 @@ To obtain it using a camera, the following code can be used:
func _input(event):
if event is InputEventMouseButton and event.pressed and event.button_index == 1:
var camera = $Camera
var from = camera.project_ray_origin(event.position)
var to = from + camera.project_ray_normal(event.position) * RAY_LENGTH
var camera3d = $Camera3D
var from = camera3d.project_ray_origin(event.position)
var to = from + camera3d.project_ray_normal(event.position) * RAY_LENGTH
.. code-tab:: csharp
@@ -261,9 +261,9 @@ To obtain it using a camera, the following code can be used:
{
if (@event is InputEventMouseButton eventMouseButton && eventMouseButton.Pressed && eventMouseButton.ButtonIndex == 1)
{
var camera = GetNode<Camera>("Camera");
var from = camera.ProjectRayOrigin(eventMouseButton.Position);
var to = from + camera.ProjectRayNormal(eventMouseButton.Position) * RayLength;
var camera3d = GetNode<Camera3D>("Camera3D");
var from = camera3d.ProjectRayOrigin(eventMouseButton.Position);
var to = from + camera3d.ProjectRayNormal(eventMouseButton.Position) * RayLength;
}
}

View File

@@ -15,12 +15,12 @@ How to control a rigid body
A rigid body's behavior can be altered by setting its properties, such as mass and weight.
A physics material needs to be added to the rigid body to adjust its friction and bounce,
and set if it's absorbent and/or rough. These properties can be set in the Inspector or via code.
See :ref:`RigidBody <class_RigidBody>` and :ref:`PhysicsMaterial <class_PhysicsMaterial>` for
See :ref:`RigidBody3D <class_RigidBody3D>` and :ref:`PhysicsMaterial <class_PhysicsMaterial>` for
the full list of properties and their effects.
There are several ways to control a rigid body's movement, depending on your desired application.
If you only need to place a rigid body once, for example to set its initial location, you can use the methods provided by the :ref:`Spatial <class_Spatial>` node, such as ``set_global_transform()`` or ``look_at()``. However, these methods cannot be called every frame or the physics engine will not be able to correctly simulate the body's state.
If you only need to place a rigid body once, for example to set its initial location, you can use the methods provided by the :ref:`Node3D <class_Node3D>` node, such as ``set_global_transform()`` or ``look_at()``. However, these methods cannot be called every frame or the physics engine will not be able to correctly simulate the body's state.
As an example, consider a rigid body that you want to rotate so that it points towards another object. A common mistake when implementing this kind of behavior is to use ``look_at()`` every frame, which breaks the physics simulation. Below, we'll demonstrate how to implement this correctly.
The fact that you can't use ``set_global_transform()`` or ``look_at()`` methods doesn't mean that you can't have full control of a rigid body. Instead, you can control it by using the ``_integrate_forces()`` callback. In this method, you can add *forces*, apply *impulses*, or set the *velocity* in order to achieve any movement you desire.
@@ -28,7 +28,7 @@ The fact that you can't use ``set_global_transform()`` or ``look_at()`` methods
The "look at" method
--------------------
As described above, using the Spatial node's ``look_at()`` method can't be used each frame to follow a target.
As described above, using the Node3D's ``look_at()`` method can't be used each frame to follow a target.
Here is a custom ``look_at()`` method that will work reliably with rigid bodies:
.. tabs::
@@ -45,7 +45,7 @@ Here is a custom ``look_at()`` method that will work reliably with rigid bodies:
state.angular_velocity = up_dir * (rotation_angle / state.step)
func _integrate_forces(state):
var target_position = $my_target_spatial_node.global_transform.origin
var target_position = $my_target_node3d_node.global_transform.origin
look_follow(state, global_transform, target_position)
.. code-tab:: csharp
@@ -64,7 +64,7 @@ Here is a custom ``look_at()`` method that will work reliably with rigid bodies:
public override void _IntegrateForces(PhysicsDirectBodyState state)
{
var targetPosition = GetNode<Spatial>("my_target_spatial_node").GetGlobalTransform().origin;
var targetPosition = GetNode<Node3D>("my_target_node3d_node").GetGlobalTransform().origin;
LookFollow(state, GetGlobalTransform(), targetPosition);
}
}
@@ -72,4 +72,4 @@ Here is a custom ``look_at()`` method that will work reliably with rigid bodies:
This method uses the rigid body's ``angular_velocity`` property to rotate the body. It first calculates the difference between the current and desired angle and then adds the velocity needed to rotate by that amount in one frame's time.
.. note:: This script will not work with rigid bodies in *character mode* because then, the body's rotation is locked. In that case, you would have to rotate the attached mesh node instead using the standard Spatial methods.
.. note:: This script will not work with rigid bodies in *character mode* because then, the body's rotation is locked. In that case, you would have to rotate the attached mesh node instead using the standard Node3D methods.

View File

@@ -9,11 +9,11 @@ This can for example be used to simulate cloth or to create more realistic chara
Basic set-up
~~~~~~~~~~~~
A :ref:`SoftBody <class_SoftBody>` node is used for soft body simulations.
A :ref:`SoftBody3D <class_SoftBody3D>` node is used for soft body simulations.
We will create a bouncy cube to demonstrate the setup of a soft body.
Create a new scene with a ``Spatial`` node as root. Then, create a ``Softbody`` node. Add a ``CubeMesh`` in the ``mesh`` property of the node in the inspector and increase the subdivision of the mesh for simulation.
Create a new scene with a ``Node3D`` node as root. Then, create a ``Softbody`` node. Add a ``CubeMesh`` in the ``mesh`` property of the node in the inspector and increase the subdivision of the mesh for simulation.
.. image:: img/softbody_cube.png

View File

@@ -342,7 +342,7 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
shoot()
func shoot():
# "Muzzle" is a Position2D placed at the barrel of the gun.
# "Muzzle" is a Marker2D placed at the barrel of the gun.
var b = Bullet.instance()
b.start($Muzzle.global_position, rotation)
get_parent().add_child(b)
@@ -386,7 +386,7 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
public void Shoot()
{
// "Muzzle" is a Position2D placed at the barrel of the gun
// "Muzzle" is a Marker2D placed at the barrel of the gun
var b = (Bullet)_bullet.Instance();
b.Start(GetNode<Node2D>("Muzzle").GlobalPosition, Rotation);
GetParent().AddChild(b);

View File

@@ -1,13 +1,13 @@
.. _doc_spatial_gizmo_plugins:
.. _doc_3d_gizmo_plugins:
Spatial gizmo plugins
=====================
3D gizmo plugins
================
Introduction
------------
Spatial gizmo plugins are used by the editor and custom plugins to define the
gizmos attached to any kind of Spatial node.
3D gizmo plugins are used by the editor and custom plugins to define the
gizmos attached to any kind of Node3D node.
This tutorial shows the two main approaches to defining your own custom
gizmos. The first option works well for simple gizmos and creates less clutter in
@@ -16,11 +16,11 @@ your plugin structure, and the second one will let you store some per-gizmo data
.. note:: This tutorial assumes you already know how to make generic plugins. If
in doubt, refer to the :ref:`doc_making_plugins` page.
The EditorSpatialGizmoPlugin
----------------------------
The EditorNode3DGizmoPlugin
---------------------------
Regardless of the approach we choose, we will need to create a new
:ref:`EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin>`. This will allow
:ref:`EditorNode3DGizmoPlugin <class_EditorNode3DGizmoPlugin>`. This will allow
us to set a name for the new gizmo type and define other behaviors such as whether
the gizmo can be hidden or not.
@@ -29,7 +29,7 @@ This would be a basic setup:
::
# MyCustomGizmoPlugin.gd
extends EditorSpatialGizmoPlugin
extends EditorNode3DGizmoPlugin
func get_name():
@@ -49,14 +49,14 @@ This would be a basic setup:
func _enter_tree():
add_spatial_gizmo_plugin(gizmo_plugin)
add_node3d_gizmo_plugin(gizmo_plugin)
func _exit_tree():
remove_spatial_gizmo_plugin(gizmo_plugin)
remove_node3d_gizmo_plugin(gizmo_plugin)
For simple gizmos, inheriting :ref:`EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin>`
For simple gizmos, inheriting :ref:`EditorNode3DGizmoPlugin <class_EditorNode3DGizmoPlugin>`
is enough. If you want to store some per-gizmo data or you are porting a Godot 3.0 gizmo
to 3.1+, you should go with the second approach.
@@ -64,21 +64,21 @@ to 3.1+, you should go with the second approach.
Simple approach
---------------
The first step is to, in our custom gizmo plugin, override the :ref:`has_gizmo()<class_EditorSpatialGizmoPlugin_method_has_gizmo>`
method so that it returns ``true`` when the spatial parameter is of our target type.
The first step is to, in our custom gizmo plugin, override the :ref:`_has_gizmo()<class_EditorNode3DGizmoPlugin_method__has_gizmo>`
method so that it returns ``true`` when the node parameter is of our target type.
::
# ...
func has_gizmo(spatial):
return spatial is MyCustomSpatial
func _has_gizmo(node):
return node is MyCustomNode3D
# ...
Then we can override methods like :ref:`redraw()<class_EditorSpatialGizmoPlugin_method_redraw>`
Then we can override methods like :ref:`_redraw()<class_EditorNode3DGizmoPlugin_method__redraw>`
or all the handle related ones.
::
@@ -94,17 +94,17 @@ or all the handle related ones.
func redraw(gizmo):
gizmo.clear()
var spatial = gizmo.get_spatial_node()
var node3d = gizmo.get_node3d()
var lines = PackedVector3Array()
lines.push_back(Vector3(0, 1, 0))
lines.push_back(Vector3(0, spatial.my_custom_value, 0))
lines.push_back(Vector3(0, node3d.my_custom_value, 0))
var handles = PackedVector3Array()
handles.push_back(Vector3(0, 1, 0))
handles.push_back(Vector3(0, spatial.my_custom_value, 0))
handles.push_back(Vector3(0, node3d.my_custom_value, 0))
gizmo.add_lines(lines, get_material("main", gizmo), false)
gizmo.add_handles(handles, get_material("handles", gizmo))
@@ -113,7 +113,7 @@ or all the handle related ones.
# ...
Note that we created a material in the `_init` method, and retrieved it in the `redraw`
method using :ref:`get_material()<class_EditorSpatialGizmoPlugin_method_get_material>`. This
method using :ref:`get_material()<class_EditorNode3DGizmoPlugin_method_get_material>`. This
method retrieves one of the material's variants depending on the state of the gizmo
(selected and/or editable).
@@ -121,10 +121,10 @@ So the final plugin would look somewhat like this:
::
extends EditorSpatialGizmoPlugin
extends EditorNode3DGizmoPlugin
const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
const MyCustomNode3D = preload("res://addons/my-addon/MyCustomNode3D.gd")
func _init():
@@ -132,54 +132,54 @@ So the final plugin would look somewhat like this:
create_handle_material("handles")
func has_gizmo(spatial):
return spatial is MyCustomSpatial
func _has_gizmo(node):
return node is MyCustomNode3D
func redraw(gizmo):
gizmo.clear()
var spatial = gizmo.get_spatial_node()
var node3d = gizmo.get_node3d()
var lines = PackedVector3Array()
lines.push_back(Vector3(0, 1, 0))
lines.push_back(Vector3(0, spatial.my_custom_value, 0))
lines.push_back(Vector3(0, node3d.my_custom_value, 0))
var handles = PackedVector3Array()
handles.push_back(Vector3(0, 1, 0))
handles.push_back(Vector3(0, spatial.my_custom_value, 0))
handles.push_back(Vector3(0, node3d.my_custom_value, 0))
gizmo.add_lines(lines, get_material("main", gizmo), false)
gizmo.add_handles(handles, get_material("handles", gizmo))
# You should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...).
# (_get_handle_name(), _get_handle_value(), _commit_handle(), ...).
Note that we just added some handles in the redraw method, but we still need to implement
the rest of handle-related callbacks in :ref:`EditorSpatialGizmoPlugin <class_EditorSpatialGizmoPlugin>`
the rest of handle-related callbacks in :ref:`EditorNode3DGizmoPlugin <class_EditorNode3DGizmoPlugin>`
to get properly working handles.
Alternative approach
--------------------
In some cases we want to provide our own implementation of :ref:`EditorSpatialGizmo<class_EditorSpatialGizmo>`,
In some cases we want to provide our own implementation of :ref:`EditorNode3DGizmo<class_EditorNode3DGizmo>`,
maybe because we want to have some state stored in each gizmo or because we are porting
an old gizmo plugin and we don't want to go through the rewriting process.
In these cases all we need to do is, in our new gizmo plugin, override
:ref:`create_gizmo()<class_EditorSpatialGizmoPlugin_method_create_gizmo>`, so it returns our custom gizmo implementation
for the Spatial nodes we want to target.
:ref:`_create_gizmo()<class_EditorNode3DGizmoPlugin_method__create_gizmo>`, so it returns our custom gizmo implementation
for the Node3D nodes we want to target.
::
# MyCustomGizmoPlugin.gd
extends EditorSpatialGizmoPlugin
extends EditorNode3DGizmoPlugin
const MyCustomSpatial = preload("res://addons/my-addon/MyCustomSpatial.gd")
const MyCustomNode3D = preload("res://addons/my-addon/MyCustomNode3D.gd")
const MyCustomGizmo = preload("res://addons/my-addon/MyCustomGizmo.gd")
@@ -188,19 +188,19 @@ for the Spatial nodes we want to target.
create_handle_material("handles")
func create_gizmo(spatial):
if spatial is MyCustomSpatial:
func _create_gizmo(node):
if node is MyCustomNode3D:
return MyCustomGizmo.new()
else:
return null
This way all the gizmo logic and drawing methods can be implemented in a new class extending
:ref:`EditorSpatialGizmo<class_EditorSpatialGizmo>`, like so:
:ref:`EditorNode3DGizmo<class_EditorNode3DGizmo>`, like so:
::
# MyCustomGizmo.gd
extends EditorSpatialGizmo
extends EditorNode3DGizmo
# You can store data in the gizmo itself (more useful when working with handles).
@@ -210,17 +210,17 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
func redraw():
clear()
var spatial = get_spatial_node()
var node3d = get_node3d()
var lines = PackedVector3Array()
lines.push_back(Vector3(0, 1, 0))
lines.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))
lines.push_back(Vector3(gizmo_size, node3d.my_custom_value, 0))
var handles = PackedVector3Array()
handles.push_back(Vector3(0, 1, 0))
handles.push_back(Vector3(gizmo_size, spatial.my_custom_value, 0))
handles.push_back(Vector3(gizmo_size, node3d.my_custom_value, 0))
var material = get_plugin().get_material("main", self)
add_lines(lines, material, false)
@@ -230,8 +230,8 @@ This way all the gizmo logic and drawing methods can be implemented in a new cla
# You should implement the rest of handle-related callbacks
# (get_handle_name(), get_handle_value(), commit_handle()...).
# (_get_handle_name(), _get_handle_value(), _commit_handle(), ...).
Note that we just added some handles in the redraw method, but we still need to implement
the rest of handle-related callbacks in :ref:`EditorSpatialGizmo<class_EditorSpatialGizmo>`
the rest of handle-related callbacks in :ref:`EditorNode3DGizmo<class_EditorNode3DGizmo>`
to get properly working handles.

View File

@@ -302,7 +302,7 @@ method. Our sample code is a bit long, so let's split in a few parts:
file.close()
The first part of our import method opens and reads the source file. We use the
:ref:`File <class_File>` class to do that, passing the ``source_file``
:ref:`FileAccess <class_FileAccess>` class to do that, passing the ``source_file``
parameter which is provided by the editor.
If there's an error when opening the file, we return it to let the editor know
@@ -410,7 +410,7 @@ system is scanned, making the custom resource appear on the FileSystem dock. If
you select it and focus the Import dock, you can see the only option to select
there.
Create a MeshInstance node in the scene, and for its Mesh property set up a new
Create a MeshInstance3D node in the scene, and for its Mesh property set up a new
SphereMesh. Unfold the Material section in the Inspector and then drag the file
from the FileSystem dock to the material property. The object will update in the
viewport with the blue color of the imported material.

View File

@@ -9,6 +9,6 @@ Editor plugins
making_plugins
making_main_screen_plugins
import_plugins
spatial_gizmos
3d_gizmos
inspector_plugins
visual_shader_plugins

View File

@@ -300,7 +300,7 @@ If you are using ``@tool``:
.. code-tab:: gdscript GDScript
func _ready():
var node = Spatial.new()
var node = Node3D.new()
add_child(node) # Parent could be any node in the scene
# The line below is required to make the node visible in the Scene tree dock
@@ -311,7 +311,7 @@ If you are using ``@tool``:
public override void _Ready()
{
var node = new Spatial();
var node = new Node3D();
AddChild(node); // Parent could be any node in the scene
// The line below is required to make the node visible in the Scene tree dock
@@ -327,7 +327,7 @@ If you are using :ref:`EditorScript<class_EditorScript>`:
func _run():
# `parent` could be any node in the scene.
var parent = get_scene().find_node("Parent")
var node = Spatial.new()
var node = Node3D.new()
parent.add_child(node)
# The line below is required to make the node visible in the Scene tree dock
@@ -340,7 +340,7 @@ If you are using :ref:`EditorScript<class_EditorScript>`:
{
// `parent` could be any node in the scene.
var parent = GetScene().FindNode("Parent");
var node = new Spatial();
var node = new Node3D();
parent.AddChild(node);
// The line below is required to make the node visible in the Scene tree dock

View File

@@ -15,7 +15,7 @@ Particles
---------
GLES2 cannot use the :ref:`GPUParticles3D <class_GPUParticles3D>` or :ref:`GPUParticles2D <class_GPUParticles2D>` nodes
as they require advanced GPU features. Instead, use :ref:`CPUParticles <class_CPUParticles>` or
as they require advanced GPU features. Instead, use :ref:`CPUParticles3D <class_CPUParticles3D>` or
:ref:`CPUParticles2D <class_CPUParticles2D>`, which provides a similar interface to a
:ref:`ParticleProcessMaterial <class_ParticleProcessMaterial>`.
@@ -100,17 +100,17 @@ can only use the first six levels of glow; the seventh one won't do anything.
GIProbes
--------
.. FIXME: Removed reference to class_BakedLightmap in master/4.0 version to
.. FIXME: Removed references to no longer existing classes in master/4.0 version to
silence warning, but the whole page will likely end up rewritten or removed
in 4.0.
:ref:`GIProbes <class_GIProbe>` do not work in GLES2. Instead use Baked Lightmaps.
GIProbes do not work in GLES2. Instead use Baked Lightmaps.
For a description of how baked lightmaps work see the :ref:`Baked Lightmaps tutorial <doc_baked_lightmaps>`.
Contact shadows
---------------
The ``shadow_contact`` property of :ref:`Lights <class_Light>` is not supported in GLES2 and so does nothing.
The ``shadow_contact`` property of lights is not supported in GLES2 and so does nothing.
Light performance
-----------------

View File

@@ -108,7 +108,7 @@ Worlds
For 3D, a :ref:`Viewport <class_Viewport>` will contain a :ref:`World3D <class_World3D>`. This
is basically the universe that links physics and rendering together.
Spatial-based nodes will register using the :ref:`World3D <class_World3D>` of the closest :ref:`Viewport <class_Viewport>`.
Node3D-based nodes will register using the :ref:`World3D <class_World3D>` of the closest :ref:`Viewport <class_Viewport>`.
By default, newly created :ref:`Viewports <class_Viewport>` do not contain a :ref:`World3D <class_World3D>` but
use the same as their parent :ref:`Viewport <class_Viewport>` (the root :ref:`Viewport <class_Viewport>` always contains a
:ref:`World3D <class_World3D>`, which is the one objects are rendered to by default). A :ref:`World3D <class_World3D>` can

View File

@@ -275,12 +275,12 @@ GDScript C#
``get_area()`` ``Area``
================ ==================================================================
Quat
----
Quaternion
----------
Structs cannot have parameterless constructors in C#. Therefore, ``new Quat()``
Structs cannot have parameterless constructors in C#. Therefore, ``new Quaternion()``
initializes all primitive members to their default value.
Please use ``Quat.Identity`` for the equivalent of ``Quat()`` in GDScript and C++.
Please use ``Quaternion.Identity`` for the equivalent of ``Quaternion()`` in GDScript and C++.
The following methods were converted to a property with a different name:

View File

@@ -13,7 +13,7 @@ Exporting is done by using the ``[Export]`` attribute.
.. code-block:: csharp
public class ExportExample : Spatial
public class ExportExample : Node3D
{
[Export]
private int Number = 5;

View File

@@ -561,8 +561,8 @@ in a 3D grid.
3D Plane type in normalized form that contains a ``normal`` vector field
and a ``d`` scalar distance.
:ref:`Quat <class_Quat>`
^^^^^^^^^^^^^^^^^^^^^^^^
:ref:`Quaternion <class_Quaternion>`
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Quaternion is a datatype used for representing a 3D rotation. It's
useful for interpolating rotations.
@@ -1686,7 +1686,7 @@ to. To create custom signals for a class, use the ``signal`` keyword.
Game Programming Patterns ebook.
You can connect these signals to methods the same way you connect built-in
signals of nodes like :ref:`class_Button` or :ref:`class_RigidBody`.
signals of nodes like :ref:`class_Button` or :ref:`class_RigidBody3D`.
In the example below, we connect the ``health_depleted`` signal from a
``Character`` node to a ``Game`` node. When the ``Character`` node emits the

View File

@@ -164,7 +164,7 @@ memory management from the Reference type.
This comes with many distinct advantages over alternative data
structures, such as JSON, CSV, or custom TXT files. Users can only import these
assets as a :ref:`Dictionary <class_Dictionary>` (JSON) or as a
:ref:`File <class_File>` to parse. What sets Resources apart is their
:ref:`FileAccess <class_FileAccess>` to parse. What sets Resources apart is their
inheritance of :ref:`Object <class_Object>`, :ref:`RefCounted <class_RefCounted>`,
and :ref:`Resource <class_Resource>` features:

View File

@@ -14,7 +14,7 @@ generally and, in particular, with the methods outlined in the :ref:`custom post
In the previous post-processing tutorial, we rendered the scene to a :ref:`Viewport <class_Viewport>`
and then rendered the Viewport in a :ref:`SubViewportContainer <class_SubViewportContainer>`
to the main scene. One limitation of this method is that we could not access the
depth buffer because the depth buffer is only available in spatial shaders and
depth buffer because the depth buffer is only available in shaders and
Viewports do not maintain depth information.
Full screen quad
@@ -27,13 +27,13 @@ two main drawbacks of using a Viewport:
1. The depth buffer cannot be accessed
2. The effect of the post-processing shader is not visible in the editor
To get around the limitation on using the depth buffer, use a :ref:`MeshInstance <class_MeshInstance>`
with a :ref:`QuadMesh <class_QuadMesh>` primitive. This allows us to use a spatial
To get around the limitation on using the depth buffer, use a :ref:`MeshInstance3D <class_MeshInstance3D>`
with a :ref:`QuadMesh <class_QuadMesh>` primitive. This allows us to use a
shader and to access the depth texture of the scene. Next, use a vertex shader
to make the quad cover the screen at all times so that the post-processing
effect will be applied at all times, including in the editor.
First, create a new MeshInstance and set its mesh to a QuadMesh. This creates a quad
First, create a new MeshInstance3D and set its mesh to a QuadMesh. This creates a quad
centered at position ``(0, 0, 0)`` with a width and height of ``1``. Set the width
and height to ``2``. Right now, the quad occupies a position in world space at the
origin; however, we want it to move with the camera so that it always covers the
@@ -156,15 +156,15 @@ screen quad. The reason for this is explained `here <https://michaldrobot.com/20
However, the benefit is quite small and only beneficial when running especially
complex fragment shaders.
Set the Mesh in the MeshInstance to an :ref:`ArrayMesh <class_ArrayMesh>`. An
Set the Mesh in the MeshInstance3D to an :ref:`ArrayMesh <class_ArrayMesh>`. An
ArrayMesh is a tool that allows you to easily construct a Mesh from Arrays for
vertices, normals, colors, etc.
Now, attach a script to the MeshInstance and use the following code:
Now, attach a script to the MeshInstance3D and use the following code:
::
extends MeshInstance
extends MeshInstance3D
func _ready():
# Create a single triangle out of vertices:
@@ -194,4 +194,4 @@ Assign the same vertex shader from above and everything should look exactly the
The one drawback to using an ArrayMesh over using a QuadMesh is that the ArrayMesh
is not visible in the editor because the triangle is not constructed until the scene
is run. To get around that, construct a single triangle Mesh in a modelling program
and use that in the MeshInstance instead.
and use that in the MeshInstance3D instead.

View File

@@ -21,7 +21,7 @@ shaders can build on themselves each run, unlike other shaders that discard the
data they have calculated once they draw to the frame buffer.
.. note:: Particle shaders are only available in the GLES3 backend. If you need
particles in GLES2, use :ref:`CPUParticles <class_CPUParticles>`.
particles in GLES2, use :ref:`CPUParticles3D <class_CPUParticles3D>`.
Render modes
^^^^^^^^^^^^

View File

@@ -15,8 +15,8 @@ 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.
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>`,
a :ref:`Camera3D <class_Camera3D>`, a :ref:`light source <class_OmniLight>`, a
:ref:`MeshInstance3D <class_MeshInstance3D>` with a :ref:`Primitive Mesh <class_PrimitiveMesh>`,
and applying a :ref:`StandardMaterial3D <class_StandardMaterial3D>` 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.
@@ -75,13 +75,13 @@ apply to the sphere.
Applying the texture
--------------------
MeshInstance > GeometryInstance > Geometry > Material Override > ``New StandardMaterial3D``:
MeshInstance3D > GeometryInstance > Geometry > Material Override > ``New StandardMaterial3D``:
Now we go into the :ref:`Mesh Instance <class_MeshInstance>` and add a :ref:`StandardMaterial3D <class_StandardMaterial3D>`
Now we go into the :ref:`MeshInstance3D <class_MeshInstance3D>` and add a :ref:`StandardMaterial3D <class_StandardMaterial3D>`
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).
MeshInstance > GeometryInstance > Geometry > Material Override > ``click`` / ``Edit``:
MeshInstance3D > GeometryInstance > Geometry > Material Override > ``click`` / ``Edit``:
Open the newly created :ref:`StandardMaterial3D <class_StandardMaterial3D>` 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.

View File

@@ -42,26 +42,26 @@ program (e.g. Blender). But Godot also has a few :ref:`PrimitiveMeshes
importing Meshes.
There are multiple node types that you can use to draw a mesh. The main one is
:ref:`MeshInstance <class_meshinstance>`, but you can also use :ref:`GPUParticles3D
:ref:`MeshInstance3D <class_MeshInstance3D>`, but you can also use :ref:`GPUParticles3D
<class_GPUParticles3D>`, :ref:`MultiMeshes <class_MultiMesh>` (with a
:ref:`MultiMeshInstance <class_multimeshinstance>`), or others.
:ref:`MultiMeshInstance3D <class_MultiMeshInstance3D>`), or others.
Typically, a material is associated with a given surface in a mesh, but some
nodes, like MeshInstance, allow you to override the material for a specific
nodes, like MeshInstance3D, allow you to override the material for a specific
surface, or for all surfaces.
If you set a material on the surface or mesh itself, then all MeshInstances that
If you set a material on the surface or mesh itself, then all MeshInstance3Ds that
share that mesh will share that material. However, if you want to reuse the same
mesh across multiple mesh instances, but have different materials for each
instance then you should set the material on the Meshinstance.
instance then you should set the material on the MeshInstance3D.
For this tutorial we will set our material on the mesh itself rather than taking
advantage of the MeshInstance's ability to override materials.
advantage of the MeshInstance3D's ability to override materials.
Setting up
----------
Add a new :ref:`MeshInstance <class_meshinstance>` node to your scene.
Add a new :ref:`MeshInstance3D <class_MeshInstance3D>` node to your scene.
In the inspector tab beside "Mesh" click "[empty]" and select "New PlaneMesh".
Then click on the image of a plane that appears.
@@ -81,7 +81,7 @@ Now set ``Subdivide Width`` and ``Subdivide Depth`` to ``32``.
.. image:: img/plane-sub-set.png
You can see that there are now many more triangles in the
:ref:`Mesh<class_MeshInstance>`. This will give us more vertices to work with
:ref:`MeshInstance3D<class_MeshInstance3D>`. This will give us more vertices to work with
and thus allow us to add more detail.
.. image:: img/plane-sub.png
@@ -111,7 +111,7 @@ because this is a spatial shader.
shader_type spatial;
Next we will define the ``vertex()`` function. The ``vertex()`` function
determines where the vertices of your :ref:`Mesh<class_MeshInstance>` appear in
determines where the vertices of your :ref:`MeshInstance3D<class_MeshInstance3D>` 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.
@@ -240,14 +240,14 @@ the shader.
::
# called from the MeshInstance
# called from the MeshInstance3D
mesh.material.set_shader_param("height_scale", 0.5)
.. note:: Changing uniforms in Spatial-based nodes is different from
CanvasItem-based nodes. Here, we set the material inside the PlaneMesh
resource. In other mesh resources you may need to first access the
material by calling ``surface_get_material()``. While in the
MeshInstance you would access the material using
MeshInstance3D you would access the material using
``get_surface_material()`` or ``material_override``.
Remember that the string passed into ``set_shader_param()`` must match the name

View File

@@ -18,7 +18,7 @@ For a full list of these parameters see the :ref:`spatial shader
A difference between the vertex function and a fragment function is that the
vertex function 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>`.
importantly, sets the ``ALBEDO`` color of the :ref:`MeshInstance3D<class_MeshInstance3D>`.
Your first spatial fragment function
------------------------------------