Browse Source

Update some of the C# documentation for 4.0 (#6681)

* Update C# documentation for 4.0

---------

Co-authored-by: Yuri Sizov <[email protected]>
Raul Santos 2 years ago
parent
commit
55dd91b1e6

+ 16 - 11
tutorials/scripting/c_sharp/c_sharp_basics.rst

@@ -82,6 +82,7 @@ external editor of choice. Godot currently supports the following
 external editors:
 external editors:
 
 
 - Visual Studio 2019
 - Visual Studio 2019
+- Visual Studio 2022
 - Visual Studio Code
 - Visual Studio Code
 - MonoDevelop
 - MonoDevelop
 - Visual Studio for Mac
 - Visual Studio for Mac
@@ -187,10 +188,11 @@ Project setup and workflow
 When you create the first C# script, Godot initializes the C# project files
 When you create the first C# script, Godot initializes the C# project files
 for your Godot project. This includes generating a C# solution (``.sln``)
 for your Godot project. This includes generating a C# solution (``.sln``)
 and a project file (``.csproj``), as well as some utility files and folders
 and a project file (``.csproj``), as well as some utility files and folders
-(``.mono`` and ``Properties/AssemblyInfo.cs``).
-All of these but ``.mono`` are important and should be committed to your
-version control system. ``.mono`` can be safely added to the ignore list of your VCS.
-When troubleshooting, it can sometimes help to delete the ``.mono`` folder
+(``.godot/mono``).
+All of these but ``.godot/mono`` are important and should be committed to your
+version control system. Everything under ``.godot`` can be safely added to the
+ignore list of your VCS.
+When troubleshooting, it can sometimes help to delete the ``.godot/mono`` folder
 and let it regenerate.
 and let it regenerate.
 
 
 Example
 Example
@@ -248,8 +250,9 @@ For more information, see the :ref:`doc_c_sharp_differences` page.
     You need to (re)build the project assemblies whenever you want to see new
     You need to (re)build the project assemblies whenever you want to see new
     exported variables or signals in the editor. This build can be manually
     exported variables or signals in the editor. This build can be manually
     triggered by clicking the word **Build** in the top right corner of the
     triggered by clicking the word **Build** in the top right corner of the
-    editor. You can also click **Mono** at the bottom of the editor window
-    to reveal the Mono panel, then click the **Build Project** button.
+    editor. You can also click **MSBuild** at the bottom of the editor window
+    to reveal the MSBuild panel, then click the **Build** button to reveal a
+    dropdown, then click the **Build Solution** option.
 
 
     You will also need to rebuild the project assemblies to apply changes in
     You will also need to rebuild the project assemblies to apply changes in
     "tool" scripts.
     "tool" scripts.
@@ -261,7 +264,7 @@ As C# support is quite new in Godot, there are some growing pains and things
 that need to be ironed out. Below is a list of the most important issues
 that need to be ironed out. Below is a list of the most important issues
 you should be aware of when diving into C# in Godot, but if in doubt, also
 you should be aware of when diving into C# in Godot, but if in doubt, also
 take a look over the official
 take a look over the official
-`issue tracker for Mono issues <https://github.com/godotengine/godot/labels/topic%3Amono>`_.
+`issue tracker for .NET issues <https://github.com/godotengine/godot/labels/topic%3Adotnet>`_.
 
 
 - Writing editor plugins is possible, but it is currently quite convoluted.
 - Writing editor plugins is possible, but it is currently quite convoluted.
 - State is currently not saved and restored when hot-reloading,
 - State is currently not saved and restored when hot-reloading,
@@ -274,11 +277,13 @@ take a look over the official
   So when using e.g. ``CallDeferred("AddChild")``, ``AddChild`` will not work because
   So when using e.g. ``CallDeferred("AddChild")``, ``AddChild`` will not work because
   the API is expecting the original ``snake_case`` version ``add_child``. However, you
   the API is expecting the original ``snake_case`` version ``add_child``. However, you
   can use any custom properties or methods without this limitation.
   can use any custom properties or methods without this limitation.
+  Prefer using the exposed ``StringName`` in the ``PropertyName``, ``MethodName`` and
+  ``SignalName`` to avoid extra ``StringName`` allocations and worrying about snake_case naming.
 
 
 
 
-As of Godot 3.2.2, exporting Mono projects is supported for desktop platforms
-(Linux, Windows and macOS), Android, HTML5, and iOS. The only platform not
-supported yet is UWP.
+As of Godot 4.0, exporting .NET projects is supported for desktop platforms
+(Linux, Windows and macOS). Other platforms will gain support in future 4.x
+releases.
 
 
 Performance of C# in Godot
 Performance of C# in Godot
 --------------------------
 --------------------------
@@ -299,7 +304,7 @@ a single code location:
 
 
     using Godot;
     using Godot;
 
 
-    public class YourCustomClass : Node3D
+    public partial class YourCustomClass : Node3D
     {
     {
         private void ExpensiveReposition()
         private void ExpensiveReposition()
         {
         {

+ 69 - 21
tutorials/scripting/c_sharp/c_sharp_differences.rst

@@ -34,7 +34,6 @@ Special cases:
 =======================  ===========================================================
 =======================  ===========================================================
 GDScript                 C#
 GDScript                 C#
 =======================  ===========================================================
 =======================  ===========================================================
-``SPKEY``                ``GD.SpKey``
 ``TYPE_*``               ``Variant.Type`` enum
 ``TYPE_*``               ``Variant.Type`` enum
 ``OP_*``                 ``Variant.Operator`` enum
 ``OP_*``                 ``Variant.Operator`` enum
 =======================  ===========================================================
 =======================  ===========================================================
@@ -46,17 +45,29 @@ Math global functions, like ``abs``, ``acos``, ``asin``, ``atan`` and ``atan2``,
 located under ``Mathf`` as ``Abs``, ``Acos``, ``Asin``, ``Atan`` and ``Atan2``.
 located under ``Mathf`` as ``Abs``, ``Acos``, ``Asin``, ``Atan`` and ``Atan2``.
 The ``PI`` constant can be found as ``Mathf.Pi``.
 The ``PI`` constant can be found as ``Mathf.Pi``.
 
 
+C# also provides static `System.Math`_ and `System.MathF`_ classes that may
+contain other useful mathematical operations.
+
+.. _System.Math: https://learn.microsoft.com/en-us/dotnet/api/system.math
+.. _System.MathF: https://learn.microsoft.com/en-us/dotnet/api/system.mathf
+
 Random functions
 Random functions
 ^^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^^
 
 
 Random global functions, like ``rand_range`` and ``rand_seed``, are located under ``GD``.
 Random global functions, like ``rand_range`` and ``rand_seed``, are located under ``GD``.
 Example: ``GD.RandRange`` and ``GD.RandSeed``.
 Example: ``GD.RandRange`` and ``GD.RandSeed``.
 
 
+Consider using `System.Random`_ or, if you need cryptographically strong randomness,
+`System.Security.Cryptography.RandomNumberGenerator`_.
+
+.. _System.Random: https://learn.microsoft.com/en-us/dotnet/api/system.random
+.. _System.Security.Cryptography.RandomNumberGenerator: https://learn.microsoft.com/en-us/dotnet/api/system.security.cryptography.randomnumbergenerator
+
 Other functions
 Other functions
 ^^^^^^^^^^^^^^^
 ^^^^^^^^^^^^^^^
 
 
-Many other global functions like ``print`` and ``var2str`` are located under ``GD``.
-Example: ``GD.Print`` and ``GD.Var2Str``.
+Many other global functions like ``print`` and ``var_to_str`` are located under ``GD``.
+Example: ``GD.Print`` and ``GD.VarToStr``.
 
 
 Exceptions:
 Exceptions:
 
 
@@ -87,10 +98,10 @@ Example:
         }
         }
     }
     }
 
 
-Export keyword
---------------
+``@export`` annotation
+----------------------
 
 
-Use the ``[Export]`` attribute instead of the GDScript ``export`` keyword.
+Use the ``[Export]`` attribute instead of the GDScript ``@export`` annotation.
 This attribute can also be provided with optional :ref:`PropertyHint<enum_@GlobalScope_PropertyHint>` and ``hintString`` parameters.
 This attribute can also be provided with optional :ref:`PropertyHint<enum_@GlobalScope_PropertyHint>` and ``hintString`` parameters.
 Default values can be set by assigning a value.
 Default values can be set by assigning a value.
 
 
@@ -115,8 +126,10 @@ Example:
         private string _icon;
         private string _icon;
     }
     }
 
 
-Signal keyword
---------------
+See also: :ref:`doc_c_sharp_exports`.
+
+``signal`` keyword
+------------------
 
 
 Use the ``[Signal]`` attribute to declare a signal instead of the GDScript ``signal`` keyword.
 Use the ``[Signal]`` attribute to declare a signal instead of the GDScript ``signal`` keyword.
 This attribute should be used on a `delegate`, whose name signature will be used to define the signal.
 This attribute should be used on a `delegate`, whose name signature will be used to define the signal.
@@ -185,8 +198,8 @@ Example:
 
 
 .. code-block:: csharp
 .. code-block:: csharp
 
 
-    string text = "Bigrams";
-    string[] bigrams = text.Bigrams(); // ["Bi", "ig", "gr", "ra", "am", "ms"]
+    string text = "Get up!";
+    string[] bigrams = text.Bigrams(); // ["Ge", "et", "t ", " u", "up", "p!"]
 
 
 Strings are immutable in .NET, so all methods that manipulate a string don't
 Strings are immutable in .NET, so all methods that manipulate a string don't
 modify the original string and return a newly created string with the
 modify the original string and return a newly created string with the
@@ -486,22 +499,52 @@ Use the ``Godot.Collections.Dictionary<T>(Godot.Collections.Dictionary)`` constr
 Variant
 Variant
 -------
 -------
 
 
-``System.Object`` (``object``) is used instead of ``Variant``.
+``Godot.Variant`` is used to represent the Godot's native :ref:`Variant <doc_variant_class>` type. Any Variant-compatible type can be converted from/to it.
+We recommend avoiding ``Godot.Variant`` unless it is necessary to interact with untyped engine APIs.
+Take advantage of C#'s type safety when possible.
+
+Any of ``Variant.As{TYPE}`` methods or the generic ``Variant.As<T>`` method can be used to convert
+a ``Godot.Variant`` to a C# type. Since the ``Godot.Variant`` type contains implicit conversions
+defined for all the supported types calling these methods directly is usually not necessary.
+
+Use ``CreateFrom`` method overloads or the generic ``From<T>`` method to convert a C# type
+to a ``Godot.Variant``.
 
 
 Communicating with other scripting languages
 Communicating with other scripting languages
 --------------------------------------------
 --------------------------------------------
 
 
 This is explained extensively in :ref:`doc_cross_language_scripting`.
 This is explained extensively in :ref:`doc_cross_language_scripting`.
 
 
-.. _doc_c_sharp_differences_yield:
+.. _doc_c_sharp_differences_await:
 
 
-Yield
------
+``await`` keyword
+-----------------
+
+Something similar to GDScript's ``await`` keyword can be achieved with C#'s
+`await keyword <https://docs.microsoft.com/en-US/dotnet/csharp/language-reference/keywords/await>`_.
+
+The ``await`` keyword in C# can be used with any awaitable expression. It's commonly
+used with operands of the types `Task`_, `Task<TResult>`_, `ValueTask`_, or `ValueTask<TResult>`_.
+
+An expression ``t`` is awaitable if one of the following holds:
 
 
-Something similar to GDScript's ``yield`` with a single parameter can be achieved with
-C#'s `yield keyword <https://docs.microsoft.com/en-US/dotnet/csharp/language-reference/keywords/yield>`_.
+* ``t`` is of compile-time type ``dynamic``.
+* ``t`` has an accessible instance or extension method called ``GetAwaiter`` with no
+  parameters and no type parameters, and a return type ``A`` for which all of the
+  following hold:
 
 
-The equivalent of yield on signal can be achieved with async/await and ``Godot.Object.ToSignal``.
+  * ``A`` implements the interface ``System.Runtime.CompilerServices.INotifyCompletion``.
+  * ``A`` has an accessible, readable instance property ``IsCompleted`` of type ``bool``.
+  * ``A`` has an accessible instance method ``GetResult`` with no parameters and no type
+    parameters.
+
+.. _Task: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task
+.. _Task<TResult>: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.task-1
+.. _ValueTask: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.valuetask
+.. _ValueTask<TResult>: https://learn.microsoft.com/en-us/dotnet/api/system.threading.tasks.valuetask-1
+
+An equivalent of awaiting a signal in GDScript can be achieved with the ``await`` keyword and
+``Godot.Object.ToSignal``.
 
 
 Example:
 Example:
 
 
@@ -522,8 +565,13 @@ Other differences:
 GDScript          C#
 GDScript          C#
 ================  ==================================================================
 ================  ==================================================================
 ``Color8``        ``Color.Color8``
 ``Color8``        ``Color.Color8``
-``is_inf``        ``float.IsInfinity``
-``is_nan``        ``float.IsNaN``
-``dict2inst``     TODO
-``inst2dict``     TODO
+``is_inf``        `float.IsInfinity`_ or `double.IsInfinity`_
+``is_nan``        `float.IsNaN`_ or `double.IsNaN`_
+``dict_to_inst``  TODO
+``inst_to_dict``  TODO
 ================  ==================================================================
 ================  ==================================================================
+
+.. _float.IsInfinity: https://learn.microsoft.com/en-us/dotnet/api/system.single.isinfinity
+.. _float.IsNaN: https://learn.microsoft.com/en-us/dotnet/api/system.single.isnan
+.. _double.IsInfinity: https://learn.microsoft.com/en-us/dotnet/api/system.double.isinfinity
+.. _double.IsNaN: https://learn.microsoft.com/en-us/dotnet/api/system.double.isnan

+ 1 - 1
tutorials/scripting/c_sharp/c_sharp_signals.rst

@@ -21,7 +21,7 @@ You can handle these events, as any other event, with the ``+=`` and ``-=`` oper
     myTimer.Timeout += () => GD.Print("Timeout!");
     myTimer.Timeout += () => GD.Print("Timeout!");
 
 
 In addition, you can always access signal names associated with a node type through its nested
 In addition, you can always access signal names associated with a node type through its nested
-``SignalName`` class. This is useful when, for example, you want to await on a signal (see :ref:`doc_c_sharp_differences_yield`).
+``SignalName`` class. This is useful when, for example, you want to await on a signal (see :ref:`doc_c_sharp_differences_await`).
 
 
 .. code-block:: csharp
 .. code-block:: csharp