Prechádzať zdrojové kódy

Added C# code to Part 1 of the FPS tutorial (#2385)

* Added C# code to Part 1 of the FPS tutorial

* Update code for FPS Tutorial Part 1

Added _ to private properties. Also removed code in the first code sample that is only added later in the tutorial.
Louis-Jacques Bourdages 6 rokov pred
rodič
commit
e4c5a12916
1 zmenil súbory, kde vykonal 214 pridanie a 8 odobranie
  1. 214 8
      tutorials/3d/fps_tutorial/part_one.rst

+ 214 - 8
tutorials/3d/fps_tutorial/part_one.rst

@@ -138,7 +138,8 @@ Attach a new script to the ``Player`` node and call it ``Player.gd``.
 Let's program our player by adding the ability to move around, look around with the mouse, and jump.
 Add the following code to ``Player.gd``:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     extends KinematicBody
 
@@ -240,6 +241,135 @@ Add the following code to ``Player.gd``:
             camera_rot.x = clamp(camera_rot.x, -70, 70)
             rotation_helper.rotation_degrees = camera_rot
 
+ .. code-tab:: csharp
+
+    using Godot;
+    using System;
+
+    public class Player : KinematicBody
+    {
+        [Export]
+        public float Gravity = -24.8f;
+        [Export]
+        public float MaxSpeed = 20.0f;
+        [Export]
+        public float JumpSpeed = 18.0f;
+        [Export]
+        public float Accel = 4.5f;
+        [Export]
+        public float Deaccel = 16.0f;
+        [Export]
+        public float MaxSlopeAngle = 40.0f;
+        [Export]
+        public float MouseSensitivity = 0.05f;
+
+        private Vector3 _vel = new Vector3();
+        private Vector3 _dir = new Vector3();
+
+        private Camera _camera;
+        private Spatial _rotationHelper;
+
+        // Called when the node enters the scene tree for the first time.
+        public override void _Ready()
+        {
+            _camera = GetNode<Camera>("Rotation_Helper/Camera");
+            _rotationHelper = GetNode<Spatial>("Rotation_Helper");
+
+            Input.SetMouseMode(Input.MouseMode.Captured);
+        }
+
+        public override void _PhysicsProcess(float delta)
+        {
+            ProcessInput(delta);
+            ProcessMovement(delta);
+        }
+
+        private void ProcessInput(float delta)
+        {
+            //  -------------------------------------------------------------------
+            //  Walking
+            _dir = new Vector3();
+            Transform camXform = _camera.GetGlobalTransform();
+
+            Vector2 inputMovementVector = new Vector2();
+
+            if (Input.IsActionPressed("movement_forward"))
+                inputMovementVector.y += 1;
+            if (Input.IsActionPressed("movement_backward"))
+                inputMovementVector.y -= 1;
+            if (Input.IsActionPressed("movement_left"))
+                inputMovementVector.x -= 1;
+            if (Input.IsActionPressed("movement_right"))
+                inputMovementVector.x += 1;
+
+            inputMovementVector = inputMovementVector.Normalized();
+
+            _dir += -camXform.basis.z.Normalized() * inputMovementVector.y;
+            _dir += camXform.basis.x.Normalized() * inputMovementVector.x;
+            //  -------------------------------------------------------------------
+
+            //  -------------------------------------------------------------------
+            //  Jumping
+            if (IsOnFloor())
+            {
+                if (Input.IsActionJustPressed("movement_jump"))
+                    _vel.y = JumpSpeed;
+            }
+            //  -------------------------------------------------------------------
+
+            //  -------------------------------------------------------------------
+            //  Capturing/Freeing the cursor
+            if (Input.IsActionJustPressed("ui_cancel"))
+            {
+                if (Input.GetMouseMode() == Input.MouseMode.Visible)
+                    Input.SetMouseMode(Input.MouseMode.Captured);
+                else
+                    Input.SetMouseMode(Input.MouseMode.Visible);
+            }
+            //  -------------------------------------------------------------------
+        }
+
+        private void ProcessMovement(float delta)
+        {
+            _dir.y = 0;
+            _dir = _dir.Normalized();
+
+            _vel.y += delta * Gravity;
+
+            Vector3 hvel = _vel;
+            hvel.y = 0;
+
+            Vector3 target = _dir;
+
+            target *= MaxSpeed;
+
+            float accel;
+            if (_dir.Dot(hvel) > 0)
+                accel = Accel;
+            else
+                accel = Deaccel;
+
+            hvel = hvel.LinearInterpolate(target, accel * delta);
+            _vel.x = hvel.x;
+            _vel.z = hvel.z;
+            _vel = MoveAndSlide(_vel, new Vector3(0, 1, 0), false, 4, Mathf.Deg2Rad(MaxSlopeAngle));
+        }
+
+        public override void _Input(InputEvent @event)
+        {
+            if (@event is InputEventMouseMotion && Input.GetMouseMode() == Input.MouseMode.Captured)
+            {
+                InputEventMouseMotion mouseEvent = @event as InputEventMouseMotion;
+                _rotationHelper.RotateX(Mathf.Deg2Rad(mouseEvent.Relative.y * MouseSensitivity));
+                RotateY(Mathf.Deg2Rad(-mouseEvent.Relative.x * MouseSensitivity));
+
+                Vector3 cameraRot = _rotationHelper.RotationDegrees;
+                cameraRot.x = Mathf.Clamp(cameraRot.x, -70, 70);
+                _rotationHelper.RotationDegrees = cameraRot;
+            }
+        }
+    }
+
 This is a lot of code, so let's break it down function by function:
 
 .. tip:: While copy and pasting code is ill advised, as you can learn a lot from manually typing the code in, you can
@@ -339,7 +469,8 @@ In Godot, the origin is at position ``(0, 0, 0)`` with a rotation of ``(0, 0, 0)
 
 If you want to move using the world space directional vectors, you'd do something like this:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if Input.is_action_pressed("movement_forward"):
         node.translate(Vector3(0, 0, 1))
@@ -349,6 +480,17 @@ If you want to move using the world space directional vectors, you'd do somethin
         node.translate(Vector3(1, 0, 0))
     if Input.is_action_pressed("movement_right"):
         node.translate(Vector3(-1, 0, 0))
+        
+ .. code-tab:: csharp
+ 
+    if (Input.IsActionPressed("movement_forward"))
+        node.Translate(new Vector3(0, 0, 1));
+    if (Input.IsActionPressed("movement_backward"))
+        node.Translate(new Vector3(0, 0, -1));
+    if (Input.IsActionPressed("movement_left"))
+        node.Translate(new Vector3(1, 0, 0));
+    if (Input.IsActionPressed("movement_right"))
+        node.Translate(new Vector3(-1, 0, 0));
 
 .. note:: Notice how we do not need to do any calculations to get world space directional vectors.
           We can define a few :ref:`Vector3 <class_Vector3>` variables and input the values pointing in each direction.
@@ -387,7 +529,8 @@ Each of those vectors point towards each of the local space vectors coming from
 
 To use the :ref:`Spatial <class_Spatial>` node's local directional vectors, we use this code:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if Input.is_action_pressed("movement_forward"):
         node.translate(node.global_transform.basis.z.normalized())
@@ -397,6 +540,17 @@ To use the :ref:`Spatial <class_Spatial>` node's local directional vectors, we u
         node.translate(node.global_transform.basis.x.normalized())
     if Input.is_action_pressed("movement_right"):
         node.translate(-node.global_transform.basis.x.normalized())
+        
+ .. code-tab:: csharp
+        
+    if (Input.IsActionPressed("movement_forward"))
+        node.Translate(node.GlobalTransform.basis.z.Normalized());
+    if (Input.IsActionPressed("movement_backward"))
+        node.Translate(-node.GlobalTransform.basis.z.Normalized());
+    if (Input.IsActionPressed("movement_left"))
+        node.Translate(node.GlobalTransform.basis.x.Normalized());
+    if (Input.IsActionPressed("movement_right"))
+        node.Translate(-node.GlobalTransform.basis.x.Normalized());
 
 Here is what local space looks like in 2D:
 
@@ -539,7 +693,8 @@ so let's do that!
 
 First we need a few more class variables in our player script:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     const MAX_SPRINT_SPEED = 30
     const SPRINT_ACCEL = 18
@@ -547,6 +702,16 @@ First we need a few more class variables in our player script:
 
     var flashlight
 
+ .. code-tab:: csharp
+
+    [Export]
+    public float MaxSprintSpeed = 30.0f;
+    [Export]
+    public float SprintAccel = 18.0f;
+    private bool _isSprinting = false;
+    
+    private SpotLight _flashlight;
+
 All the sprinting variables work exactly the same as the non sprinting variables with
 similar names.
 
@@ -555,17 +720,23 @@ we will be using to hold the player's flash light node.
 
 Now we need to add a few lines of code, starting in ``_ready``. Add the following to ``_ready``:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     flashlight = $Rotation_Helper/Flashlight
 
+ .. code-tab:: csharp
+ 
+    _flashlight = GetNode<SpotLight>("Rotation_Helper/Flashlight");
+
 This gets the ``Flashlight`` node and assigns it to the ``flashlight`` variable.
 
 _________
 
 Now we need to change some of the code in ``process_input``. Add the following somewhere in ``process_input``:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     # ----------------------------------
     # Sprinting
@@ -584,6 +755,26 @@ Now we need to change some of the code in ``process_input``. Add the following s
             flashlight.show()
     # ----------------------------------
 
+ .. code-tab:: csharp
+ 
+    //  -------------------------------------------------------------------
+    //  Sprinting
+    if (Input.IsActionPressed("movement_sprint"))
+        _isSprinting = true;
+    else
+        _isSprinting = false;
+    //  -------------------------------------------------------------------
+
+    //  -------------------------------------------------------------------
+    //  Turning the flashlight on/off
+    if (Input.IsActionJustPressed("flashlight"))
+    {
+        if (_flashlight.IsVisibleInTree())
+            _flashlight.Hide();
+        else
+            _flashlight.Show();
+    }
+
 Let's go over the additions:
 
 We set ``is_sprinting`` to true when the player is holding down the ``movement_sprint`` action, and false
@@ -597,25 +788,40 @@ _________
 
 Now we need to change a couple things in ``process_movement``. First, replace ``target *= MAX_SPEED`` with the following:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if is_sprinting:
         target *= MAX_SPRINT_SPEED
     else:
         target *= MAX_SPEED
 
+ .. code-tab:: csharp
+ 
+    if (_isSprinting)
+        target *= MaxSprintSpeed;    
+    else
+        target *= MaxSpeed;
+            
 Now instead of always multiplying ``target`` by ``MAX_SPEED``, we first check to see if the player is sprinting or not.
 If the player is sprinting, we instead multiply ``target`` by ``MAX_SPRINT_SPEED``.
 
 Now all that's left is to change the acceleration when sprinting. Change ``accel = ACCEL`` to the following:
 
-::
+.. tabs::
+ .. code-tab:: gdscript GDScript
 
     if is_sprinting:
         accel = SPRINT_ACCEL
     else:
         accel = ACCEL
 
+ .. code-tab:: csharp
+ 
+    if (_isSprinting)
+        accel = SprintAccel;
+    else
+        accel = Accel;
 
 Now, when the player is sprinting, we'll use ``SPRINT_ACCEL`` instead of ``ACCEL``, which will accelerate the player faster.