mirror of
https://github.com/godotengine/godot-docs.git
synced 2025-12-31 17:49:03 +03:00
Kinematic -> Character
This commit is contained in:
@@ -333,3 +333,4 @@ source,destination
|
||||
/tutorials/viewports/multiple_resolutions.html,/tutorials/rendering/multiple_resolutions.html
|
||||
/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
|
||||
|
||||
|
@@ -270,14 +270,14 @@ From the Oxford dictionary:
|
||||
|
||||
::
|
||||
|
||||
Create a KinematicBody2D node, a CollisionShape2D node and a sprite node.
|
||||
Create a CharacterBody2D node, a CollisionShape2D node and a sprite node.
|
||||
|
||||
**Do** add a comma before `and` or `or`, for the last
|
||||
element of a list with more than two elements.
|
||||
|
||||
::
|
||||
|
||||
Create a KinematicBody2D node, a CollisionShape2D node, and a sprite node.
|
||||
Create a CharacterBody2D node, a CollisionShape2D node, and a sprite node.
|
||||
|
||||
|
||||
How to write methods and classes
|
||||
@@ -483,7 +483,7 @@ The Animation, Debugger, etc. at the bottom of the viewport are
|
||||
|
||||
Foldable areas of the Inspector are ``sections``. The node's parent
|
||||
class names, which you can't fold, are ``Classes`` e.g. the
|
||||
``KinematicBody2D class``. And individual lines with key-value pairs are
|
||||
``CharacterBody2D class``. And individual lines with key-value pairs are
|
||||
``properties``. E.g. ``position`` or ``modulate color`` are both
|
||||
``properties``.
|
||||
|
||||
|
||||
@@ -11,11 +11,11 @@ that moves in eight directions.
|
||||
.. player_movement.gif
|
||||
|
||||
Create a new scene by going to the Scene menu in the top-left and clicking *New
|
||||
Scene*. Create a *KinematicBody* node as the root and name it *Player*.
|
||||
Scene*. Create a *CharacterBody3D* node as the root and name it *Player*.
|
||||
|
||||
|image0|
|
||||
|
||||
Kinematic bodies are complementary to the area and rigid bodies used in the 2D
|
||||
Character bodies are complementary to the area and rigid bodies used in the 2D
|
||||
game tutorial. Like rigid bodies, they can move and collide with the
|
||||
environment, but instead of being controlled by the physics engine, you dictate
|
||||
their movement. You will see how we use the node's unique features when we code
|
||||
|
||||
@@ -19,7 +19,7 @@ character.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# How fast the player moves in meters per second.
|
||||
@export var speed = 14
|
||||
@@ -30,7 +30,7 @@ character.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Player : KinematicBody
|
||||
public class Player : CharacterBody3D
|
||||
{
|
||||
// Don't forget to rebuild the project so the editor knows about the new export variable.
|
||||
|
||||
@@ -214,8 +214,8 @@ The physics engine can only detect interactions with walls, the floor, or other
|
||||
bodies during a given frame if movement and collisions happen. We will use this
|
||||
property later to code the jump.
|
||||
|
||||
On the last line, we call ``KinematicBody.move_and_slide()``. It's a powerful
|
||||
method of the ``KinematicBody`` class that allows you to move a character
|
||||
On the last line, we call ``CharacterBody3D.move_and_slide()``. It's a powerful
|
||||
method of the ``CharacterBody3D`` class that allows you to move a character
|
||||
smoothly. If it hits a wall midway through a motion, the engine will try to
|
||||
smooth it out for you.
|
||||
|
||||
@@ -233,7 +233,7 @@ Here is the complete ``Player.gd`` code for reference.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# How fast the player moves in meters per second.
|
||||
@export var speed = 14
|
||||
@@ -266,7 +266,7 @@ Here is the complete ``Player.gd`` code for reference.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Player : KinematicBody
|
||||
public class Player : CharacterBody3D
|
||||
{
|
||||
// How fast the player moves in meters per second.
|
||||
[Export]
|
||||
|
||||
@@ -9,7 +9,7 @@ next lesson, we'll spawn them randomly around the playable area.
|
||||
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 *KinematicBody* node as its root. Name it
|
||||
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
|
||||
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
|
||||
@@ -100,7 +100,7 @@ the ``velocity``.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# Minimum speed of the mob in meters per second.
|
||||
@export var min_speed = 10
|
||||
@@ -115,7 +115,7 @@ the ``velocity``.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Mob : KinematicBody
|
||||
public class Mob : CharacterBody3D
|
||||
{
|
||||
// Don't forget to rebuild the project so the editor knows about the new export variable.
|
||||
|
||||
@@ -135,7 +135,7 @@ the ``velocity``.
|
||||
}
|
||||
|
||||
Similarly to the player, we move the mob every frame by calling
|
||||
``KinematicBody``\ 's ``move_and_slide()`` method. This time, we don't update
|
||||
``CharacterBody3D``\ 's ``move_and_slide()`` method. This time, we don't update
|
||||
the ``velocity`` every frame: we want the monster to move at a constant speed
|
||||
and leave the screen, even if it were to hit an obstacle.
|
||||
|
||||
@@ -254,7 +254,7 @@ Here is the complete ``Mob.gd`` script for reference.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# Minimum speed of the mob in meters per second.
|
||||
@export var min_speed = 10
|
||||
@@ -281,7 +281,7 @@ Here is the complete ``Mob.gd`` script for reference.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Mob : KinematicBody
|
||||
public class Mob : CharacterBody3D
|
||||
{
|
||||
// Minimum speed of the mob in meters per second
|
||||
[Export]
|
||||
|
||||
@@ -157,7 +157,7 @@ called ``move_and_slide()``.
|
||||
|
||||
That's all you need to jump!
|
||||
|
||||
The ``is_on_floor()`` method is a tool from the ``KinematicBody`` class. It
|
||||
The ``is_on_floor()`` method is a tool from the ``CharacterBody3D`` class. It
|
||||
returns ``true`` if the body collided with the floor in this frame. That's why
|
||||
we apply gravity to the *Player*: so we collide with the floor instead of
|
||||
floating over it like the monsters.
|
||||
@@ -258,7 +258,7 @@ With this code, if no collisions occurred on a given frame, the loop won't run.
|
||||
for (int index = 0; index < GetSlideCount(); index++)
|
||||
{
|
||||
// We check every collision that occurred this frame.
|
||||
KinematicCollision collision = GetSlideCollision(index);
|
||||
KinematicCollision3D collision = GetSlideCollision(index);
|
||||
// If we collide with a monster...
|
||||
if (collision.Collider is Mob mob && mob.IsInGroup("mob"))
|
||||
{
|
||||
@@ -276,11 +276,11 @@ With this code, if no collisions occurred on a given frame, the loop won't run.
|
||||
That's a lot of new functions. Here's some more information about them.
|
||||
|
||||
The functions ``get_slide_count()`` and ``get_slide_collision()`` both come from
|
||||
the :ref:`KinematicBody<class_KinematicBody>` class and are related to
|
||||
the :ref:`CharacterBody3D<class_CharacterBody3D>` class and are related to
|
||||
``move_and_slide()``.
|
||||
|
||||
``get_slide_collision()`` returns a
|
||||
:ref:`KinematicCollision<class_KinematicCollision>` object that holds
|
||||
:ref:`KinematicCollision3D<class_KinematicCollision3D>` object that holds
|
||||
information about where and how the collision occurred. For example, we use its
|
||||
``collider`` property to check if we collided with a "mob" by calling
|
||||
``is_in_group()`` on it: ``collision.collider.is_in_group("mob")``.
|
||||
|
||||
@@ -52,7 +52,7 @@ one to the *Player* node. In the *Node* tab, double-click the
|
||||
|
||||
|image4|
|
||||
|
||||
The *MobDetector* will emit ``body_entered`` when a *KinematicBody* or a
|
||||
The *MobDetector* will emit ``body_entered`` when a *CharacterBody3D* or a
|
||||
*RigidBody* node enters it. As it only masks the "enemies" physics
|
||||
layers, it will only detect the *Mob* nodes.
|
||||
|
||||
@@ -228,7 +228,7 @@ Next is ``Mob.gd``.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# Emitted when the player jumped on the mob.
|
||||
signal squashed
|
||||
@@ -264,7 +264,7 @@ Next is ``Mob.gd``.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Mob : KinematicBody
|
||||
public class Mob : CharacterBody3D
|
||||
{
|
||||
// Emitted when the played jumped on the mob.
|
||||
[Signal]
|
||||
@@ -311,7 +311,7 @@ Finally, the longest script, ``Player.gd``.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# Emitted when a mob hit the player.
|
||||
signal hit
|
||||
@@ -373,7 +373,7 @@ Finally, the longest script, ``Player.gd``.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Player : KinematicBody
|
||||
public class Player : CharacterBody3D
|
||||
{
|
||||
// Emitted when the player was hit by a mob.
|
||||
[Signal]
|
||||
@@ -435,7 +435,7 @@ Finally, the longest script, ``Player.gd``.
|
||||
|
||||
for (int index = 0; index < GetSlideCount(); index++)
|
||||
{
|
||||
KinematicCollision collision = GetSlideCollision(index);
|
||||
KinematicCollision3D collision = GetSlideCollision(index);
|
||||
if (collision.Collider is Mob mob && mob.IsInGroup("mob"))
|
||||
{
|
||||
if (Vector3.Up.Dot(collision.Normal) > 0.1f)
|
||||
|
||||
@@ -282,7 +282,7 @@ Here's the *Player* script.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# Emitted when the player was hit by a mob.
|
||||
signal hit
|
||||
@@ -349,7 +349,7 @@ Here's the *Player* script.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Player : KinematicBody
|
||||
public class Player : CharacterBody3D
|
||||
{
|
||||
// Emitted when the player was hit by a mob.
|
||||
[Signal]
|
||||
@@ -416,7 +416,7 @@ Here's the *Player* script.
|
||||
|
||||
for (int index = 0; index < GetSlideCount(); index++)
|
||||
{
|
||||
KinematicCollision collision = GetSlideCollision(index);
|
||||
KinematicCollision3D collision = GetSlideCollision(index);
|
||||
if (collision.Collider is Mob mob && mob.IsInGroup("mob"))
|
||||
{
|
||||
if (Vector3.Up.Dot(collision.Normal) > 0.1f)
|
||||
@@ -449,7 +449,7 @@ And the *Mob*'s script.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
# Emitted when the player jumped on the mob.
|
||||
signal squashed
|
||||
@@ -487,7 +487,7 @@ And the *Mob*'s script.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Mob : KinematicBody
|
||||
public class Mob : CharacterBody3D
|
||||
{
|
||||
// Emitted when the played jumped on the mob.
|
||||
[Signal]
|
||||
|
||||
@@ -40,7 +40,7 @@ nodes.
|
||||
|
||||
.. image:: img/key_concepts_character_nodes.png
|
||||
|
||||
It is made of a ``KinematicBody2D`` node named "Character", a ``Sprite2D``, a
|
||||
It is made of a ``CharacterBody2D`` node named "Character", a ``Sprite2D``, a
|
||||
``Camera2D``, and a ``CollisionShape2D``.
|
||||
|
||||
.. note:: The node names end with "2D" because this is a 2D scene. Their 3D
|
||||
|
||||
@@ -10,7 +10,7 @@ Every beginner has been there: "How do I move my character?" Depending on the
|
||||
style of game you're making, you may have special requirements, but in general
|
||||
the movement in most 2D games is based on a small number of designs.
|
||||
|
||||
We'll use :ref:`KinematicBody2D <class_KinematicBody2D>` for these examples,
|
||||
We'll use :ref:`CharacterBody2D <class_CharacterBody2D>` for these examples,
|
||||
but the principles will apply to other node types (Area2D, RigidBody2D) as well.
|
||||
|
||||
.. _doc_2d_movement_setup:
|
||||
@@ -18,7 +18,7 @@ but the principles will apply to other node types (Area2D, RigidBody2D) as well.
|
||||
Setup
|
||||
-----
|
||||
|
||||
Each example below uses the same scene setup. Start with a ``KinematicBody2D`` with two
|
||||
Each example below uses the same scene setup. Start with a ``CharacterBody2D`` with two
|
||||
children: ``Sprite2D`` and ``CollisionShape2D``. You can use the Godot icon ("icon.png")
|
||||
for the Sprite2D's texture or use any other 2D image you have.
|
||||
|
||||
@@ -41,7 +41,7 @@ Add a script to the kinematic body and add the following code:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
export (int) var speed = 200
|
||||
|
||||
@@ -68,7 +68,7 @@ Add a script to the kinematic body and add the following code:
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class Movement : KinematicBody2D
|
||||
public class Movement : CharacterBody2D
|
||||
{
|
||||
[Export] public int speed = 200;
|
||||
|
||||
@@ -129,7 +129,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
export (int) var speed = 200
|
||||
export (float) var rotation_speed = 1.5
|
||||
@@ -159,7 +159,7 @@ while up/down moves it forward or backward in whatever direction it's facing.
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class Movement : KinematicBody2D
|
||||
public class Movement : CharacterBody2D
|
||||
{
|
||||
[Export] public int speed = 200;
|
||||
[Export] public float rotationSpeed = 1.5f;
|
||||
@@ -216,7 +216,7 @@ is set by the mouse position instead of the keyboard. The character will always
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
export (int) var speed = 200
|
||||
|
||||
@@ -239,7 +239,7 @@ is set by the mouse position instead of the keyboard. The character will always
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class Movement : KinematicBody2D
|
||||
public class Movement : CharacterBody2D
|
||||
{
|
||||
[Export] public int speed = 200;
|
||||
|
||||
@@ -291,7 +291,7 @@ on the screen will cause the player to move to the target location.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
export (int) var speed = 200
|
||||
|
||||
@@ -313,7 +313,7 @@ on the screen will cause the player to move to the target location.
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class Movement : KinematicBody2D
|
||||
public class Movement : CharacterBody2D
|
||||
{
|
||||
[Export] public int speed = 200;
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ released.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
onready var _animated_sprite = $AnimatedSprite2D
|
||||
|
||||
@@ -88,7 +88,7 @@ released.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Character : KinematicBody2D
|
||||
public class Character : CharacterBody2D
|
||||
{
|
||||
private AnimatedSprite2D _animatedSprite;
|
||||
|
||||
@@ -215,7 +215,7 @@ released.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
onready var _animation_player = $AnimationPlayer
|
||||
|
||||
@@ -227,7 +227,7 @@ released.
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
public class Character : KinematicBody2D
|
||||
public class Character : CharacterBody2D
|
||||
{
|
||||
private AnimationPlayer _animationPlayer;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ Creating the polygons
|
||||
---------------------
|
||||
|
||||
Create a new scene for your model (if it's going to be an animated character,
|
||||
you may want to use a ``KinematicBody2D``). For ease of use, an empty 2D node is
|
||||
you may want to use a ``CharacterBody2D``). For ease of use, an empty 2D node is
|
||||
created as a root for the polygons.
|
||||
|
||||
Begin with a ``Polygon2D`` node. There is no need to place it anywhere in the
|
||||
|
||||
@@ -33,7 +33,7 @@ This is how it's done in the `Third Person Shooter demo <https://github.com/godo
|
||||
|
||||
.. image:: img/animtree1.png
|
||||
|
||||
A new scene was created for the player with a ``KinematicBody`` as root. Inside this scene, the original ``.dae`` (Collada) file was instantiated
|
||||
A new scene was created for the player with a ``CharacterBody3D`` as root. Inside this scene, the original ``.dae`` (Collada) file was instantiated
|
||||
and an ``AnimationTree`` node was created.
|
||||
|
||||
Creating a tree
|
||||
@@ -211,7 +211,7 @@ Afterwards, the actual motion can be retrieved via the :ref:`AnimationTree <clas
|
||||
|
||||
animTree.GetRootMotionTransform();
|
||||
|
||||
This can be fed to functions such as :ref:`KinematicBody.move_and_slide <class_KinematicBody_method_move_and_slide>` to control the character movement.
|
||||
This can be fed to functions such as :ref:`CharacterBody3D.move_and_slide <class_CharacterBody3D_method_move_and_slide>` to control the character movement.
|
||||
|
||||
There is also a tool node, ``RootMotionView``, that can be placed in a scene and will act as a custom floor for your
|
||||
character and animations (this node is disabled by default during the game).
|
||||
|
||||
@@ -222,8 +222,8 @@ The surface normal has a value of ``(0, -1)`` because this is a horizontal
|
||||
surface. When the ball collides, we take its remaining motion (the amount left
|
||||
over when it hits the surface) and reflect it using the normal. In Godot, the
|
||||
:ref:`Vector2 <class_Vector2>` class has a ``bounce()`` method to handle this.
|
||||
Here is a GDScript example of the diagram above using a :ref:`KinematicBody2D
|
||||
<class_KinematicBody2D>`:
|
||||
Here is a GDScript example of the diagram above using a :ref:`CharacterBody2D
|
||||
<class_CharacterBody2D>`:
|
||||
|
||||
|
||||
.. tabs::
|
||||
|
||||
@@ -3,22 +3,22 @@
|
||||
Using NavigationAgents
|
||||
======================
|
||||
|
||||
NavigationsAgents are helper nodes to facilitate common calls to the NavigationServer API
|
||||
NavigationsAgents are helper nodes to facilitate common calls to the NavigationServer API
|
||||
on behalf of the parent actor node in a more convenient manner for beginners.
|
||||
|
||||
2D and 3D version of NavigationAgents are available as
|
||||
:ref:`NavigationAgent2D<class_NavigationAgent2D>` and
|
||||
2D and 3D version of NavigationAgents are available as
|
||||
:ref:`NavigationAgent2D<class_NavigationAgent2D>` and
|
||||
:ref:`NavigationAgent3D<class_NavigationAgent3D>` respectively.
|
||||
|
||||
NavigationsAgents are entirely optional for navigation pathfinding.
|
||||
The functionality of NavigationsAgents can be recreated with scripts and direct
|
||||
calls to the NavigationServer API. If the default NavigationsAgent does not do what you want
|
||||
NavigationsAgents are entirely optional for navigation pathfinding.
|
||||
The functionality of NavigationsAgents can be recreated with scripts and direct
|
||||
calls to the NavigationServer API. If the default NavigationsAgent does not do what you want
|
||||
for your game feel free to design your own NavigationsAgent with scripts.
|
||||
|
||||
.. warning::
|
||||
|
||||
NavigationsAgent nodes and NavigationServer ``agents`` are not the same.
|
||||
The later is an RVO avoidance agent and solely used for avoidance.
|
||||
NavigationsAgent nodes and NavigationServer ``agents`` are not the same.
|
||||
The later is an RVO avoidance agent and solely used for avoidance.
|
||||
RVO avoidance agents are not involved in regular pathfinding.
|
||||
|
||||
NavigationAgent Pathfinding
|
||||
@@ -27,23 +27,23 @@ NavigationAgent Pathfinding
|
||||
To use NavigationAgents for pathfinding, place a NavigationAgent2D/3D Node below a Node2D/3D inheriting parent node.
|
||||
|
||||
To have the agent query a path to a target position use the ``set_target_location()`` method.
|
||||
Once the target has been set, the next position to follow in the path
|
||||
can be retrieved with the ``get_next_location()`` function. Move the parent actor node
|
||||
to this position with your own movement code. On the next ``physics_frame``, call
|
||||
Once the target has been set, the next position to follow in the path
|
||||
can be retrieved with the ``get_next_location()`` function. Move the parent actor node
|
||||
to this position with your own movement code. On the next ``physics_frame``, call
|
||||
``get_next_location()`` again for the next position and repeat this until the path ends.
|
||||
|
||||
NavigationAgents have their own internal logic to proceed with the current path and call for updates.
|
||||
NavigationAgents recognize by distance when a path point or the final target is reached.
|
||||
NavigationAgents refresh a path automatically when too far away from the current pathpoint.
|
||||
The important updates are all triggered with the ``get_next_location()`` function
|
||||
The important updates are all triggered with the ``get_next_location()`` function
|
||||
when called in ``_physics_process()``.
|
||||
|
||||
Be careful calling other NavigationAgent functions not required for path movement
|
||||
Be careful calling other NavigationAgent functions not required for path movement
|
||||
while the actor is following a path, as many function trigger a full path refresh.
|
||||
|
||||
.. note::
|
||||
|
||||
New NavigationAgents will automatically join the
|
||||
New NavigationAgents will automatically join the
|
||||
default navigation map for their 2D/3D dimension.
|
||||
|
||||
.. warning::
|
||||
@@ -68,8 +68,8 @@ They work well out of the box with :ref:`CharacterBody2D<class_CharacterBody2D>`
|
||||
NavigationAgent Avoidance
|
||||
-------------------------
|
||||
|
||||
This section explains how to use the built-in avoidance specific
|
||||
to NavigationAgent nodes. For general avoidance use and more technical details
|
||||
This section explains how to use the built-in avoidance specific
|
||||
to NavigationAgent nodes. For general avoidance use and more technical details
|
||||
on RVO avoidance see :ref:`doc_navigation_using_agent_avoidance`.
|
||||
|
||||
|
||||
@@ -87,8 +87,8 @@ The following NavigationAgent properties are relevant for avoidance:
|
||||
- The property ``neighbor_distance`` controls the search radius of the agent when searching for other agents that should be avoided. A lower value reduces processing cost.
|
||||
- The property ``max_neighbors`` controls how many other agents are considered in the avoidance calculation if they all have overlapping radius.
|
||||
A lower value reduces processing cost but a too low value may result in agents ignoring the avoidance.
|
||||
- The property ``time_horizion`` controls the avoidance maneuver start and end distance.
|
||||
How early and for how long an agents reacts to other agents within the ``neighbor_distance`` radius to correct its own velocity.
|
||||
- The property ``time_horizion`` controls the avoidance maneuver start and end distance.
|
||||
How early and for how long an agents reacts to other agents within the ``neighbor_distance`` radius to correct its own velocity.
|
||||
A lower value results in avoidance kicking in with a very intense velocity change at a short distance while a high value results in very early but small velocity changes.
|
||||
- The property ``max_speed`` controls the maximum velocity assumed for the agents avoidance calculation.
|
||||
If the agents parents moves faster than this value the avoidance ``safe_velocity`` might not be accurate enough to avoid collision.
|
||||
@@ -99,12 +99,12 @@ The ``velocity_computed`` signal of the agent node must be connected to receive
|
||||
|
||||
Additional the current velocity of the agents parent must be set for the agent in ``_physics_process()`` with ``set_velocity()``.
|
||||
|
||||
After a short wait for processing the avoidance (still in the same frame) the ``safe_velocity`` vector will be received with the signal.
|
||||
After a short wait for processing the avoidance (still in the same frame) the ``safe_velocity`` vector will be received with the signal.
|
||||
This velocity vector should be used to move the NavigationAgent's parent node in order to avoidance collision with other avoidance registered agents in proximity.
|
||||
|
||||
RVO exists in its own space and has no information from navigation meshes or physics collision.
|
||||
Behind the scene avoidance agents are just circles with different radius on a flat plane.
|
||||
In narrow places obstructed with collision objects, the avoidance maneuver radius needs to be
|
||||
In narrow places obstructed with collision objects, the avoidance maneuver radius needs to be
|
||||
reduced considerably or disabled else the avoidance velocity will get actors stuck on collision easily.
|
||||
|
||||
.. note::
|
||||
@@ -113,19 +113,19 @@ reduced considerably or disabled else the avoidance velocity will get actors stu
|
||||
|
||||
.. warning::
|
||||
|
||||
Actors that move according to their avoidance agent velocity will not move at
|
||||
full speed, can leave the navigation mesh bounds and can make movement
|
||||
Actors that move according to their avoidance agent velocity will not move at
|
||||
full speed, can leave the navigation mesh bounds and can make movement
|
||||
pauses when the avoidance simulation becomes unsolvable.
|
||||
|
||||
Using the NavigationAgent ``enable_avoidance`` property is the preferred option
|
||||
to toggle avoidance but the following scripts for NavigationAgents can be
|
||||
Using the NavigationAgent ``enable_avoidance`` property is the preferred option
|
||||
to toggle avoidance but the following scripts for NavigationAgents can be
|
||||
used to create or delete avoidance callbacks for the agent RID.
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends NavigationAgent2D
|
||||
|
||||
|
||||
var agent : RID = get_rid()
|
||||
NavigationServer2D::get_singleton()->agent_set_callback(agent, self, "_avoidance_done")
|
||||
NavigationServer2D::get_singleton()->agent_set_callback(agent, null, "_avoidance_done")
|
||||
@@ -134,7 +134,7 @@ used to create or delete avoidance callbacks for the agent RID.
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends NavigationAgent3D
|
||||
|
||||
|
||||
var agent : RID = get_rid()
|
||||
NavigationServer3D::get_singleton()->agent_set_callback(agent, self, "_avoidance_done")
|
||||
NavigationServer3D::get_singleton()->agent_set_callback(agent, null, "_avoidance_done")
|
||||
@@ -192,14 +192,14 @@ This script adds basic navigation movement to a CharacterBody3D with a Navigatio
|
||||
navigation_agent.set_target_location(movement_target)
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
|
||||
var next_path_position : Vector3 = navigation_agent.get_next_location()
|
||||
var current_agent_position : Vector3 = global_transform.origin
|
||||
var new_velocity : Vector3 = (next_path_position - current_agent_position).normalized() * movement_speed
|
||||
navigation_agent.set_velocity(new_velocity)
|
||||
|
||||
func _on_NavigationAgent3D_velocity_computed(safe_velocity : Vector3):
|
||||
# Move KinematicBody3D with the computed `safe_velocity` to avoid dynamic obstacles.
|
||||
# Move CharacterBody3D with the computed `safe_velocity` to avoid dynamic obstacles.
|
||||
velocity = safe_velocity
|
||||
move_and_slide()
|
||||
|
||||
@@ -220,12 +220,12 @@ This script adds basic navigation movement to a RigidBody3D with a NavigationAge
|
||||
navigation_agent.set_target_location(movement_target)
|
||||
|
||||
func _physics_process(delta):
|
||||
|
||||
|
||||
var next_path_position : Vector3 = navigation_agent.get_next_location()
|
||||
var current_agent_position : Vector3 = global_transform.origin
|
||||
var new_velocity : Vector3 = (next_path_position - current_agent_position).normalized() * velocity
|
||||
navigation_agent.set_velocity(new_velocity)
|
||||
|
||||
|
||||
func _on_NavigationAgent3D_velocity_computed(safe_velocity : Vector3):
|
||||
# Move RigidBody3D with the computed `safe_velocity` to avoid dynamic obstacles.
|
||||
set_linear_velocity(safe_velocity)
|
||||
|
||||
@@ -8,7 +8,7 @@ Physics
|
||||
physics_introduction
|
||||
rigid_body
|
||||
using_area_2d
|
||||
using_kinematic_body_2d
|
||||
using_character_body_2d
|
||||
ray-casting
|
||||
ragdoll_system
|
||||
kinematic_character_2d
|
||||
|
||||
@@ -56,7 +56,7 @@ or lose precision if the frame rate is too high or too low.
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
func _physics_process(delta):
|
||||
pass
|
||||
@@ -66,7 +66,7 @@ or lose precision if the frame rate is too high or too low.
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class PhysicsScript : KinematicBody2D
|
||||
public class PhysicsScript : CharacterBody2D
|
||||
{
|
||||
public override void _PhysicsProcess(float delta)
|
||||
{
|
||||
@@ -111,7 +111,7 @@ Moving the kinematic character
|
||||
Go back to the character scene, and open the script, the magic begins
|
||||
now! Kinematic body will do nothing by default, but it has a
|
||||
useful function called
|
||||
:ref:`KinematicBody2D.move_and_collide() <class_KinematicBody2D_method_move_and_collide>`.
|
||||
:ref:`CharacterBody2D.move_and_collide() <class_CharacterBody2D_method_move_and_collide>`.
|
||||
This function takes a :ref:`Vector2 <class_Vector2>` as
|
||||
an argument, and tries to apply that motion to the kinematic body. If a
|
||||
collision happens, it stops right at the moment of the collision.
|
||||
@@ -121,7 +121,7 @@ So, let's move our sprite downwards until it hits the floor:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
func _physics_process(delta):
|
||||
move_and_collide(Vector2(0, 1)) # Move down 1 pixel per physics frame
|
||||
@@ -131,7 +131,7 @@ So, let's move our sprite downwards until it hits the floor:
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class PhysicsScript : KinematicBody2D
|
||||
public class PhysicsScript : CharacterBody2D
|
||||
{
|
||||
public override void _PhysicsProcess(float delta)
|
||||
{
|
||||
@@ -149,7 +149,7 @@ little more like a regular game character:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
const GRAVITY = 200.0
|
||||
var velocity = Vector2()
|
||||
@@ -165,7 +165,7 @@ little more like a regular game character:
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class PhysicsScript : KinematicBody2D
|
||||
public class PhysicsScript : CharacterBody2D
|
||||
{
|
||||
const float gravity = 200.0f;
|
||||
Vector2 velocity;
|
||||
@@ -188,7 +188,7 @@ This adds basic support for walking when pressing left and right:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
const GRAVITY = 200.0
|
||||
const WALK_SPEED = 200
|
||||
@@ -216,7 +216,7 @@ This adds basic support for walking when pressing left and right:
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class PhysicsScript : KinematicBody2D
|
||||
public class PhysicsScript : CharacterBody2D
|
||||
{
|
||||
const float gravity = 200.0f;
|
||||
const int walkSpeed = 200;
|
||||
|
||||
@@ -47,7 +47,7 @@ The other three bodies extend :ref:`PhysicsBody2D <class_PhysicsBody2D>`:
|
||||
``RigidBody2D`` directly, but instead you apply forces to it (gravity, impulses,
|
||||
etc.) and the physics engine calculates the resulting movement. :ref:`Read more about using rigid bodies. <doc_rigid_body>`
|
||||
|
||||
- :ref:`KinematicBody2D <class_KinematicBody2D>`
|
||||
- :ref:`CharacterBody2D <class_CharacterBody2D>`
|
||||
A body that provides collision detection, but no physics. All movement and
|
||||
collision response must be implemented in code.
|
||||
|
||||
@@ -233,16 +233,6 @@ 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
|
||||
a collision or via code.
|
||||
|
||||
Rigid body modes
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
A rigid body can be set to one of four modes:
|
||||
|
||||
- **Rigid** - The body behaves as a physical object. It collides with other bodies and responds to forces applied to it. This is the default mode.
|
||||
- **Static** - The body behaves like a :ref:`StaticBody2D <class_StaticBody2D>` and does not move.
|
||||
- **Character** - Similar to "Rigid" mode, but the body cannot rotate.
|
||||
- **Kinematic** - The body behaves like a :ref:`KinematicBody2D <class_KinematicBody2D>` and must be moved by code.
|
||||
|
||||
Using RigidBody2D
|
||||
~~~~~~~~~~~~~~~~~
|
||||
|
||||
@@ -330,28 +320,28 @@ Contact monitoring via signals can be enabled via the :ref:`contact_monitor <cla
|
||||
property. See :ref:`RigidBody2D <class_RigidBody2D>` for the list of available
|
||||
signals.
|
||||
|
||||
KinematicBody2D
|
||||
CharacterBody2D
|
||||
---------------
|
||||
|
||||
:ref:`KinematicBody2D <class_KinematicBody2D>` bodies detect collisions with
|
||||
:ref:`CharacterBody2D <class_CharacterBody2D>` bodies detect collisions with
|
||||
other bodies, but are not affected by physics properties like gravity or friction.
|
||||
Instead, they must be controlled by the user via code. The physics engine will
|
||||
not move a kinematic body.
|
||||
not move a character body.
|
||||
|
||||
When moving a kinematic body, you should not set its ``position`` directly.
|
||||
When moving a character body, you should not set its ``position`` directly.
|
||||
Instead, you use the ``move_and_collide()`` or ``move_and_slide()`` methods.
|
||||
These methods move the body along a given vector, and it will instantly stop
|
||||
if a collision is detected with another body. After the body has collided,
|
||||
any collision response must be coded manually.
|
||||
|
||||
Kinematic collision response
|
||||
Character collision response
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
After a collision, you may want the body to bounce, to slide along a wall,
|
||||
or to alter the properties of the object it hit. The way you handle collision
|
||||
response depends on which method you used to move the KinematicBody2D.
|
||||
response depends on which method you used to move the CharacterBody2D.
|
||||
|
||||
:ref:`move_and_collide <class_KinematicBody2D_method_move_and_collide>`
|
||||
:ref:`move_and_collide <class_CharacterBody2D_method_move_and_collide>`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
When using ``move_and_collide()``, the function returns a
|
||||
@@ -365,7 +355,7 @@ occurred:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
var velocity = Vector2(250, 250)
|
||||
|
||||
@@ -376,7 +366,7 @@ occurred:
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
class Body : KinematicBody2D
|
||||
class Body : CharacterBody2D
|
||||
{
|
||||
private Vector2 _velocity = new Vector2(250, 250);
|
||||
|
||||
@@ -395,7 +385,7 @@ Or to bounce off of the colliding object:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
var velocity = Vector2(250, 250)
|
||||
|
||||
@@ -406,7 +396,7 @@ Or to bounce off of the colliding object:
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
class Body : KinematicBody2D
|
||||
class Body : CharacterBody2D
|
||||
{
|
||||
private Vector2 _velocity = new Vector2(250, 250);
|
||||
|
||||
@@ -418,7 +408,7 @@ Or to bounce off of the colliding object:
|
||||
}
|
||||
}
|
||||
|
||||
:ref:`move_and_slide <class_KinematicBody2D_method_move_and_slide>`
|
||||
:ref:`move_and_slide <class_CharacterBody2D_method_move_and_slide>`
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Sliding is a common collision response; imagine a player moving along walls
|
||||
@@ -437,7 +427,7 @@ the ground (including slopes) and jump when standing on the ground:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
var run_speed = 350
|
||||
var jump_speed = -1000
|
||||
@@ -465,7 +455,7 @@ the ground (including slopes) and jump when standing on the ground:
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
class Body : KinematicBody2D
|
||||
class Body : CharacterBody2D
|
||||
{
|
||||
private float _runSpeed = 350;
|
||||
private float _jumpSpeed = -1000;
|
||||
|
||||
@@ -79,7 +79,7 @@ You can also limit the simulation to only a few bones. To do so, pass the bone n
|
||||
Collision layer and mask
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Make sure to set up your collision layers and masks properly so the ``KinematicBody``'s capsule doesn't get in the way of the physics simulation:
|
||||
Make sure to set up your collision layers and masks properly so the ``CharacterBody3D``'s capsule doesn't get in the way of the physics simulation:
|
||||
|
||||
.. image:: img/ragdoll_layer.png
|
||||
|
||||
|
||||
@@ -163,13 +163,13 @@ as shown in the following image:
|
||||
|
||||
To avoid self-intersection, the ``intersect_ray()`` function can take an
|
||||
optional third parameter which is an array of exceptions. This is an
|
||||
example of how to use it from a KinematicBody2D or any other
|
||||
example of how to use it from a CharacterBody2D or any other
|
||||
collision object node:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
func _physics_process(delta):
|
||||
var space_state = get_world_2d().direct_space_state
|
||||
@@ -177,7 +177,7 @@ collision object node:
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
class Body : KinematicBody2D
|
||||
class Body : CharacterBody2D
|
||||
{
|
||||
public override void _PhysicsProcess(float delta)
|
||||
{
|
||||
@@ -202,7 +202,7 @@ member variable:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
func _physics_process(delta):
|
||||
var space_state = get_world().direct_space_state
|
||||
@@ -211,7 +211,7 @@ member variable:
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
class Body : KinematicBody2D
|
||||
class Body : CharacterBody2D
|
||||
{
|
||||
public override void _PhysicsProcess(float delta)
|
||||
{
|
||||
|
||||
@@ -61,7 +61,7 @@ Here's the node setup for the coin:
|
||||
|
||||
To detect the overlap, we'll connect the appropriate signal on the Area2d. Which
|
||||
signal to use depends on the player's node type. If the player is another area,
|
||||
use ``area_entered``. However, let's assume our player is a ``KinematicBody2D``
|
||||
use ``area_entered``. However, let's assume our player is a ``CharacterBody2D``
|
||||
(and therefore a ``CollisionObject2D`` type), so we'll connect the
|
||||
``body_entered`` signal.
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.. _doc_using_kinematic_body_2d:
|
||||
.. _doc_using_character_body_2d:
|
||||
|
||||
Using KinematicBody2D
|
||||
Using CharacterBody2D
|
||||
=====================
|
||||
|
||||
Introduction
|
||||
@@ -10,32 +10,32 @@ Godot offers several collision objects to provide both collision detection
|
||||
and response. Trying to decide which one to use for your project can be confusing.
|
||||
You can avoid problems and simplify development if you understand how each of them
|
||||
works and what their pros and cons are. In this tutorial, we'll look at the
|
||||
:ref:`KinematicBody2D <class_KinematicBody2D>` node and show some examples
|
||||
:ref:`CharacterBody2D <class_CharacterBody2D>` node and show some examples
|
||||
of how to use it.
|
||||
|
||||
.. note:: This document assumes you're familiar with Godot's various physics
|
||||
bodies. Please read :ref:`doc_physics_introduction` first.
|
||||
|
||||
What is a kinematic body?
|
||||
What is a character body?
|
||||
-------------------------
|
||||
|
||||
``KinematicBody2D`` is for implementing bodies that are controlled via code.
|
||||
Kinematic bodies detect collisions with other bodies when moving, but are not affected by
|
||||
``CharacterBody2D`` is for implementing bodies that are controlled via code.
|
||||
Character bodies detect collisions with other bodies when moving, but are not affected by
|
||||
engine physics properties, like gravity or friction. While this means that you
|
||||
have to write some code to create their behavior, it also means you have more
|
||||
precise control over how they move and react.
|
||||
|
||||
.. tip:: A `KinematicBody2D` can be affected by gravity and other forces,
|
||||
.. tip:: A `CharacterBody2D` can be affected by gravity and other forces,
|
||||
but you must calculate the movement in code. The physics engine will
|
||||
not move a `KinematicBody2D`.
|
||||
not move a `CharacterBody2D`.
|
||||
|
||||
Movement and collision
|
||||
----------------------
|
||||
|
||||
When moving a ``KinematicBody2D``, you should not set its ``position`` property
|
||||
When moving a ``CharacterBody2D``, you should not set its ``position`` property
|
||||
directly. Instead, you use the ``move_and_collide()`` or ``move_and_slide()`` methods.
|
||||
These methods move the body along a given vector and instantly stop if
|
||||
a collision is detected with another body. After a KinematicBody2D has collided,
|
||||
a collision is detected with another body. After a CharacterBody2D has collided,
|
||||
any *collision response* must be coded manually.
|
||||
|
||||
.. warning:: You should only do Kinematic body movement in the ``_physics_process()`` callback.
|
||||
@@ -129,7 +129,7 @@ and ``get_slide_collision()``:
|
||||
for i in get_slide_count():
|
||||
var collision = get_slide_collision(i)
|
||||
print("I collided with ", collision.collider.name)
|
||||
|
||||
|
||||
.. code-tab:: csharp
|
||||
|
||||
// Using MoveAndCollide.
|
||||
@@ -216,7 +216,7 @@ Movement and walls
|
||||
|
||||
If you've downloaded the sample project, this example is in "BasicMovement.tscn".
|
||||
|
||||
For this example, add a ``KinematicBody2D`` with two children: a ``Sprite2D`` and a
|
||||
For this example, add a ``CharacterBody2D`` with two children: a ``Sprite2D`` and a
|
||||
``CollisionShape2D``. Use the Godot "icon.png" as the Sprite2D's texture (drag it
|
||||
from the Filesystem dock to the *Texture* property of the ``Sprite2D``). In the
|
||||
``CollisionShape2D``'s *Shape* property, select "New RectangleShape2D" and
|
||||
@@ -224,12 +224,12 @@ size the rectangle to fit over the sprite image.
|
||||
|
||||
.. note:: See :ref:`doc_2d_movement` for examples of implementing 2D movement schemes.
|
||||
|
||||
Attach a script to the KinematicBody2D and add the following code:
|
||||
Attach a script to the CharacterBody2D and add the following code:
|
||||
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
var speed = 250
|
||||
var velocity = Vector2()
|
||||
@@ -256,7 +256,7 @@ Attach a script to the KinematicBody2D and add the following code:
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class KBExample : KinematicBody2D
|
||||
public class KBExample : CharacterBody2D
|
||||
{
|
||||
public int Speed = 250;
|
||||
private Vector2 _velocity = new Vector2();
|
||||
@@ -294,7 +294,7 @@ some obstacles. Add a :ref:`StaticBody2D <class_StaticBody2D>` with a
|
||||
rectangular collision shape. For visibility, you can use a sprite, a
|
||||
Polygon2D, or turn on "Visible Collision Shapes" from the "Debug" menu.
|
||||
|
||||
Run the scene again and try moving into the obstacle. You'll see that the ``KinematicBody2D``
|
||||
Run the scene again and try moving into the obstacle. You'll see that the ``CharacterBody2D``
|
||||
can't penetrate the obstacle. However, try moving into the obstacle at an angle and
|
||||
you'll find that the obstacle acts like glue - it feels like the body gets stuck.
|
||||
|
||||
@@ -325,7 +325,7 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
var Bullet = preload("res://Bullet.tscn")
|
||||
var speed = 200
|
||||
@@ -360,7 +360,7 @@ uses the mouse pointer. Here is the code for the Player, using ``move_and_slide(
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class KBExample : KinematicBody2D
|
||||
public class KBExample : CharacterBody2D
|
||||
{
|
||||
private PackedScene _bullet = (PackedScene)GD.Load("res://Bullet.tscn");
|
||||
public int Speed = 200;
|
||||
@@ -411,7 +411,7 @@ And the code for the Bullet:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
var speed = 750
|
||||
var velocity = Vector2()
|
||||
@@ -436,7 +436,7 @@ And the code for the Bullet:
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class Bullet : KinematicBody2D
|
||||
public class Bullet : CharacterBody2D
|
||||
{
|
||||
public int Speed = 750;
|
||||
private Vector2 _velocity = new Vector2();
|
||||
@@ -498,7 +498,7 @@ Here's the code for the player body:
|
||||
.. tabs::
|
||||
.. code-tab:: gdscript GDScript
|
||||
|
||||
extends KinematicBody2D
|
||||
extends CharacterBody2D
|
||||
|
||||
export (int) var run_speed = 100
|
||||
export (int) var jump_speed = -400
|
||||
@@ -533,7 +533,7 @@ Here's the code for the player body:
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class KBExample : KinematicBody2D
|
||||
public class KBExample : CharacterBody2D
|
||||
{
|
||||
[Export] public int RunSpeed = 100;
|
||||
[Export] public int JumpSpeed = -400;
|
||||
@@ -620,7 +620,7 @@ Use PascalCase for class and node names:
|
||||
|
||||
::
|
||||
|
||||
extends KinematicBody
|
||||
extends CharacterBody3D
|
||||
|
||||
Also use PascalCase when loading a class into a constant or a variable:
|
||||
|
||||
|
||||
@@ -149,7 +149,7 @@ Type casting is a key concept in typed languages.
|
||||
Casting is the conversion of a value from one type to another.
|
||||
|
||||
Imagine an Enemy in your game, that ``extends Area2D``. You want it to
|
||||
collide with the Player, a ``KinematicBody2D`` with a script called
|
||||
collide with the Player, a ``CharacterBody2D`` with a script called
|
||||
``PlayerController`` attached to it. You use the ``on_body_entered``
|
||||
signal to detect the collision. With typed code, the body you detect is
|
||||
going to be a generic ``PhysicsBody2D``, and not your
|
||||
@@ -198,7 +198,7 @@ don't care about the node's type as long as it has the methods you need
|
||||
to call.
|
||||
|
||||
You can use casting to tell Godot the type you expect when you get a
|
||||
node: ``($Timer as Timer)``, ``($Player as KinematicBody2D)``, etc.
|
||||
node: ``($Timer as Timer)``, ``($Player as CharacterBody2D)``, etc.
|
||||
Godot will ensure the type works and if so, the line number will turn
|
||||
green at the left of the script editor.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user