mirror of
https://github.com/godotengine/godot-docs.git
synced 2026-01-05 22:09:56 +03:00
Improve docs structure
Change Step by Step in Getting Started Remove Engine Features category, move into a new Tutorials top-level section
This commit is contained in:
140
getting_started/scripting/c_sharp/c_sharp_basics.rst
Normal file
140
getting_started/scripting/c_sharp/c_sharp_basics.rst
Normal file
@@ -0,0 +1,140 @@
|
||||
.. _doc_c_sharp:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
.. warning:: C# support is a new feature in Godot 3.0.
|
||||
As such, you may still run into some issues, or find spots where the documentation could be improved.
|
||||
Please report issues with C# in Godot on the `engine Github page <https://github.com/godotengine/godot/issues>`_.
|
||||
And any documentation issues on the `documentation Github Page <https://github.com/godotengine/godot-docs/issues>`_.
|
||||
|
||||
This page provides a brief intro to C#, both what it is and how to use it in Godot.
|
||||
Afterwards, you may want to look at :ref:`how to use specific features <doc_c_sharp_features>`,
|
||||
read about the :ref:`differences between the C# and the GDScript API <doc_c_sharp_differences>`
|
||||
and (re)visit the :ref:`Scripting section <doc_scripting>` of the step-by-step tutorial.
|
||||
|
||||
C# is a high-level programming language developed by Microsoft. In Godot it is implemented with the Mono 5.2 .NET framework including full support for C# 7.0.
|
||||
Mono is an open source implementation of Microsoft's .NET Framework based on the ECMA standards for C# and the Common Language Runtime.
|
||||
A good starting point for checking its capabilities is the `Compatibility <http://www.mono-project.com/docs/about-mono/compatibility/>`_ page in the Mono documentation.
|
||||
|
||||
.. note:: This is **not** a full-scale tutorial on the C# language as a whole.
|
||||
If you aren't already familiar with its syntax or features,
|
||||
see the `Microsoft C# guide <https://docs.microsoft.com/en-us/dotnet/csharp/index>`_ or look for a suitable introduction elsewhere.
|
||||
|
||||
Setup C# for Godot
|
||||
------------------
|
||||
|
||||
To use C# in Godot you must have `Mono <http://www.mono-project.com/download/>`_ installed (at least version 5.2).
|
||||
|
||||
Additionally, your Godot version must have Mono support enabled, so take care to download the **Mono version** of Godot.
|
||||
If you are building Godot from source, make sure to follow the steps to include Mono support in your build outlined on the :ref:`doc_compiling_with_mono` page.
|
||||
|
||||
Windows users also need MS Build 15.0, which comes bundled with Visual Studio 2017,
|
||||
or can be downloaded separately with `build tools for Visual Studio 2017 <https://www.visualstudio.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=15#>`_.
|
||||
|
||||
Configuring an external editor
|
||||
------------------------------
|
||||
|
||||
While Godot does have its own scripting editor, its support for C# is kept
|
||||
minimal, and it's recommended that you use an external IDE or editor, such as
|
||||
Microsoft Visual Studio Code, or MonoDevelop, which provide auto-completion,
|
||||
debugging and other features useful when working with C#.
|
||||
To set it up, in Godot click on ``Editor``, then ``Editor Settings``. Scroll
|
||||
down to the bottom, to the ``Mono`` settings. Under Mono click on ``Editor``,
|
||||
and on that page choose your external editor of choice.
|
||||
|
||||
Creating a C# script
|
||||
--------------------
|
||||
|
||||
After you successfully setup C# for Godot, you should see the following option when selecting ``Attach script`` in the context menu of a node in your scene:
|
||||
|
||||
.. image:: img/attachcsharpscript.png
|
||||
|
||||
Note that while some specifics change, most of the things work the same when using C# for scripting.
|
||||
If you're new to Godot, you may want to peruse the tutorials on :ref:`doc_scripting` at this point.
|
||||
While some places in the documentation still lack C# examples, most things can be transferred easily from GDScript.
|
||||
|
||||
Project setup and workflow
|
||||
--------------------------
|
||||
|
||||
When you create the first C# script, Godot initializes the C# project files for your Godot project.
|
||||
This includes generating a C# solution (``.sln``) and project (``.csproj``) as well as some utility files and folders (``.mono``, sometimes ``Properties``).
|
||||
All of these but ``.mono`` are important and should be kept in your version control system. ``.mono`` can be safely added to the ignore list of your VCS.
|
||||
When troubleshooting, it sometimes can help to delete the ``.mono`` folder and let it regenerate.
|
||||
|
||||
Note that currently there are some issues where the Godot and the C# project don't stay in sync; if you delete, rename or move things like scripts or nodes, they may no longer match up.
|
||||
In this case, it can help to edit the solution files manually.
|
||||
|
||||
Example: If you created a script (e.g. ``Test.cs``) and delete it in Godot, compilation will fail because the now missing file is still expected to be there by the CS project.
|
||||
You can for now simply open up the ``.csproj`` and look for the ``ItemGroup``, there should be a line included like the following:
|
||||
|
||||
.. code-block:: xml
|
||||
:emphasize-lines: 2
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="Test.cs" />``
|
||||
<Compile Include="AnotherTest.cs" />``
|
||||
</ItemGroup>
|
||||
|
||||
Simply remove that line and your project should now again build fine. Same for renaming and moving things, simply rename and move them in the project file if needed.
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Here's a blank C# script with some comments to demonstrate how it works.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
public class YourCustomClass : Node
|
||||
{
|
||||
// Member variables here, example:
|
||||
private int a = 2;
|
||||
private string b = "textvar";
|
||||
|
||||
public override void _Ready()
|
||||
{
|
||||
// Called every time the node is added to the scene.
|
||||
// Initialization here
|
||||
GD.Print("Hello from C# to Godot :)");
|
||||
}
|
||||
|
||||
public override void _Process(float delta)
|
||||
{
|
||||
// Called every frame. Delta is time since last frame.
|
||||
// Update game logic here.
|
||||
}
|
||||
}
|
||||
|
||||
As you can see, the things normally in global scope in GDScript like Godot's ``print`` function are available in the ``GD`` namespace.
|
||||
For a list of those, see the class reference pages for :ref:`@GDScript <class_@gdscript>` and :ref:`@GlobalScope <class_@globalscope>`.
|
||||
|
||||
General differences between C# and GDScript
|
||||
-------------------------------------------
|
||||
|
||||
The C# API uses ``PascalCase`` instead of ``snake_case`` in GDScript/C++.
|
||||
Where possible, fields and getters/setters have been converted to properties.
|
||||
In general, the C# Godot API strives to be as idiomatic as is reasonably possible.
|
||||
|
||||
For more, see the :ref:`doc_c_sharp_differences` page.
|
||||
|
||||
Current gotchas and known issues
|
||||
--------------------------------
|
||||
|
||||
As C# support is quite new to Godot, there are some growing pains and things that still 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 take a look over the official `issue tracker for Mono issues <https://github.com/godotengine/godot/labels/topic%3Amono>`_.
|
||||
|
||||
- As explained above, the C# project isn't always kept in sync automatically when things are deleted, renamed or moved in Godot (`#12917 <https://github.com/godotengine/godot/issues/12917>`_)
|
||||
- Signals can only be added with ``add_user_signal()`` and don't show up in UI (`#11956 <https://github.com/godotengine/godot/issues/11956>`_)
|
||||
- Debug output like stack traces, file path and line numbers is missing on Windows (`#14589 <https://github.com/godotengine/godot/issues/14589>`_)
|
||||
- Writing editor plugins and tool scripts in C# is not yet supported
|
||||
- Exporting a project may not yet work
|
||||
|
||||
Performance of C# in Godot
|
||||
--------------------------
|
||||
|
||||
According to some preliminary `benchmarks <https://github.com/cart/godot3-bunnymark>`_, performance of C# in Godot - while generally in the same order of magnitude - is roughly **~4x** that of GDScript in some naive cases.
|
||||
For full performance, C++ is still a little faster; the specifics are going to vary according to your use case. GDScript is likely fast enough for most general scripting workloads.
|
||||
C# is faster, but requires some expensive marshalling when talking to Godot.
|
||||
220
getting_started/scripting/c_sharp/c_sharp_differences.rst
Normal file
220
getting_started/scripting/c_sharp/c_sharp_differences.rst
Normal file
@@ -0,0 +1,220 @@
|
||||
.. _doc_c_sharp_differences:
|
||||
|
||||
API differences to GDScript
|
||||
===========================
|
||||
|
||||
This is a (incomplete) list of API differences between C# and GDScript.
|
||||
|
||||
General Differences
|
||||
-------------------
|
||||
|
||||
As explained in the :ref:`doc_c_sharp`, C# generally uses ``PascalCase`` instead
|
||||
of the ``snake_case`` in GDScript and C++.
|
||||
|
||||
Global Scope
|
||||
------------
|
||||
|
||||
Available under ``Godot.GD``.
|
||||
Some things were moved to their own classes, like Math and Random. See below.
|
||||
|
||||
Global functions like ``print``, ``var2str`` and ``weakref`` are located under
|
||||
``GD`` in C#.
|
||||
|
||||
``ERR_*`` constants were moved to ``Godot.Error``.
|
||||
|
||||
Math
|
||||
----
|
||||
|
||||
Math functions like ``abs``, ``acos``, ``asin``, ``atan`` and ``atan2`` are
|
||||
located under ``Mathf`` instead of in global scope.
|
||||
``PI`` is ``Mathf.PI``
|
||||
|
||||
Random
|
||||
------
|
||||
|
||||
Random functions like ``rand_range`` and ``rand_seed`` are located under ``Random``,
|
||||
so use ``Random.RandRange`` instead of ``rand_range``.
|
||||
|
||||
Export keyword
|
||||
--------------
|
||||
|
||||
Use the ``[Export]`` attribute instead of the GDScript ``export`` keyword.
|
||||
|
||||
Singletons
|
||||
----------
|
||||
|
||||
Singletons provide static methods rather than using the singleton pattern in C#.
|
||||
This is to make code less verbose and similar to GDScript. Example:
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
Input.IsActionPressed("ui_down")
|
||||
|
||||
String
|
||||
------
|
||||
|
||||
Use ``System.String`` (``string``). All the Godot String methods are provided
|
||||
by the ``StringExtensions`` class as extension methods. Example:
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
string upper = "I LIKE SALAD FORKS";
|
||||
string lower = upper.ToLower();
|
||||
|
||||
There are a few differences though:
|
||||
|
||||
* ``erase``: Strings are immutable in C#, so we cannot modify the string
|
||||
passed to the extension method. For this reason ``Erase`` was added as an
|
||||
extension method of ``StringBuilder`` instead of string.
|
||||
Alternatively you can use ``string.Remove``.
|
||||
* ``IsSubsequenceOf``/``IsSubsequenceOfi``: An additional method is provided
|
||||
which is an overload of ``IsSubsequenceOf`` allowing to explicitly specify
|
||||
case sensitivity:
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
str.IsSubsequenceOf("ok"); // Case sensitive
|
||||
str.IsSubsequenceOf("ok", true); // Case sensitive
|
||||
str.IsSubsequenceOfi("ok"); // Case insensitive
|
||||
str.IsSubsequenceOf("ok", false); // Case insensitive
|
||||
|
||||
* ``Match``/``Matchn``/``ExprMatch``: An additional method is provided besides
|
||||
``Match`` and ``Matchn``, which allows to explicitly specify case sensitivity:
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
str.Match("*.txt"); // Case sensitive
|
||||
str.ExprMatch("*.txt", true); // Case sensitive
|
||||
str.Matchn("*.txt"); // Case insensitive
|
||||
str.ExprMatch("*.txt", false); // Case insensitive
|
||||
|
||||
Basis
|
||||
-----
|
||||
|
||||
Structs cannot have parameterless constructors in C#, therefore ``new Basis()``
|
||||
initializes all primitive members to their default value. Use ``Basis.Identity``
|
||||
for the equivalent to ``Basis()`` in GDScript and C++.
|
||||
|
||||
The following methods were converted to properties with their respective names changed:
|
||||
|
||||
================ ==================================================================
|
||||
GDScript C#
|
||||
================ ==================================================================
|
||||
get_scale() Scale
|
||||
================ ==================================================================
|
||||
|
||||
Transform2D
|
||||
-----------
|
||||
|
||||
Structs cannot have parameterless constructors in C#, therefore ``new Transform2D()``
|
||||
initializes all primitive members to their default value.
|
||||
Please use ``Transform2D.Identity`` for the equivalent to ``Transform2D()`` in GDScript and C++.
|
||||
|
||||
The following methods were converted to properties with their respective names changed:
|
||||
|
||||
================ ==================================================================
|
||||
GDScript C#
|
||||
================ ==================================================================
|
||||
get_origin() Origin
|
||||
get_rotation() Rotation
|
||||
get_scale() Scale
|
||||
================ ==================================================================
|
||||
|
||||
Plane
|
||||
-----
|
||||
|
||||
The following methods were converted to properties with their respective names changed:
|
||||
|
||||
================ ==================================================================
|
||||
GDScript C#
|
||||
================ ==================================================================
|
||||
center() Center
|
||||
================ ==================================================================
|
||||
|
||||
Rect2
|
||||
-----
|
||||
|
||||
The following fields were converted to properties with their respective names changed:
|
||||
|
||||
================ ==================================================================
|
||||
GDScript C#
|
||||
================ ==================================================================
|
||||
end End
|
||||
================ ==================================================================
|
||||
|
||||
The following methods were converted to properties with their respective names changed:
|
||||
|
||||
================ ==================================================================
|
||||
GDScript C#
|
||||
================ ==================================================================
|
||||
get_area() Area
|
||||
================ ==================================================================
|
||||
|
||||
Quat
|
||||
----
|
||||
|
||||
Structs cannot have parameterless constructors in C#, therefore ``new Quat()``
|
||||
initializes all primitive members to their default value.
|
||||
Please use ``Quat.Identity`` for the equivalent to ``Quat()`` in GDScript and C++.
|
||||
|
||||
Array
|
||||
-----
|
||||
|
||||
*This is temporary. Array is ref-counted, so it will need its own type that wraps the native side.
|
||||
PoolArrays will also need their own type to be used the way they are meant to.*
|
||||
|
||||
================ ==================================================================
|
||||
GDScript C#
|
||||
================ ==================================================================
|
||||
Array object[]
|
||||
PoolIntArray int[]
|
||||
PoolByteArray byte[]
|
||||
PoolFloatArray float[]
|
||||
PoolStringArray String[]
|
||||
PoolColorArray Color[]
|
||||
PoolVector2Array Vector2[]
|
||||
PoolVector3Array Vector3[]
|
||||
================ ==================================================================
|
||||
|
||||
In some exceptional cases a raw array (``type[]``) may be required instead of a ``List``.
|
||||
|
||||
Dictionary
|
||||
----------
|
||||
|
||||
*This is temporary. Array is ref-counted, so it will need its own type that wraps the native side.*
|
||||
|
||||
Use ``Dictionary<object, object>``.
|
||||
|
||||
Variant
|
||||
-------
|
||||
|
||||
``System.Object`` (``object``) is used in place of ``Variant``.
|
||||
|
||||
Communicating with other scripting languages
|
||||
--------------------------------------------
|
||||
|
||||
The methods ``object Object.call(string method, params object[] args)``,
|
||||
``object Object.get(string field)`` and ``object Object.set(string field, object value)``
|
||||
are provided to communicate with instances of other
|
||||
scripting languages via the Variant API.
|
||||
|
||||
Other differences
|
||||
-----------------
|
||||
|
||||
``preload``, ``assert`` and ``yield`` as they work in GDScript are currently
|
||||
not available in C#.
|
||||
|
||||
Other differences:
|
||||
|
||||
================ ==================================================================
|
||||
GDScript C#
|
||||
================ ==================================================================
|
||||
Color8 Color.Color8
|
||||
is_inf float.IsInfinity
|
||||
is_nan float.IsNaN
|
||||
dict2inst ? TODO
|
||||
inst2dict ? TODO
|
||||
load GD.load which is the same as ResourceLoader.load
|
||||
================ ==================================================================
|
||||
|
||||
|
||||
93
getting_started/scripting/c_sharp/c_sharp_features.rst
Normal file
93
getting_started/scripting/c_sharp/c_sharp_features.rst
Normal file
@@ -0,0 +1,93 @@
|
||||
.. _doc_c_sharp_features:
|
||||
|
||||
Features
|
||||
============
|
||||
|
||||
This page provied an overview over the commonly used features of both C# and Godot
|
||||
and how they are used together.
|
||||
|
||||
Type Conversion and Casting
|
||||
---------------------------
|
||||
|
||||
C# is a statically typed language. Therefore you can't do the following:
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
var mySprite = GetNode("MySprite")
|
||||
mySprite.SetFrame(0)
|
||||
|
||||
The method ``GetNode()`` returns a ``Node`` instance.
|
||||
You must explicitly convert it to the desired derived type, ``Sprite`` in this case.
|
||||
|
||||
For this, you have various options in C#.
|
||||
|
||||
**Casting and Type Checking**
|
||||
|
||||
Throws ``InvalidCastException`` if the returned node cannot be casted to Sprite.
|
||||
You would use it instead of the ``as`` operator if you are pretty sure it won't fail.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
Sprite mySprite = (Sprite)GetNode("MySprite");
|
||||
mySprite.SetFrame(0);
|
||||
|
||||
**Using the AS operator**
|
||||
|
||||
The ``as`` operator returns null if the node cannot be casted to Sprite,
|
||||
and for this reason it cannot be used with value types.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
Sprite mySprite = GetNode("MySprite") as Sprite;
|
||||
// Only call SetFrame() is mySprite is not null
|
||||
mySprite?.SetFrame(0);;
|
||||
|
||||
**Type checking using the IS operator**
|
||||
|
||||
To check if the node can be casted to Sprite, you can use the ``is`` operator.
|
||||
The ``is`` operator returns false if the node cannot be casted to Sprite,
|
||||
otherwise it returns true.
|
||||
|
||||
.. code-block:: csharp
|
||||
|
||||
if (GetNode("MySprite") is Sprite)
|
||||
{
|
||||
// Yup, it's a sprite!
|
||||
}
|
||||
|
||||
For more advanced type checking, you can look into `Pattern Matching <https://docs.microsoft.com/en-us/dotnet/csharp/pattern-matching>`_.
|
||||
|
||||
Signals
|
||||
-------
|
||||
|
||||
For a complete C# example, see the **Handling a signal** section in the step by step :ref:`doc_scripting` tutorial.
|
||||
|
||||
You can use ``Connect("SomeSignal", someObject, "SomeMethod")`` to connect to signals.
|
||||
``AddUserSignal("SignalName")`` is used to define custom signals.
|
||||
Emitting signals is done with ``EmitSignal("SignalName")``. Params can be given, like ``EmitSignal("SignalName", arg1, arg2, ...)``.
|
||||
|
||||
**Custom signals**
|
||||
|
||||
.. code-block:: csharp
|
||||
:emphasize-lines: 5, 10
|
||||
:linenos:
|
||||
|
||||
public class ExampleScript : Node
|
||||
{
|
||||
public override void _Ready()
|
||||
{
|
||||
AddUserSignal("YourSignal");
|
||||
}
|
||||
|
||||
public override void _Process(float delta)
|
||||
{
|
||||
EmitSignal("YourSignal");
|
||||
}
|
||||
}
|
||||
|
||||
Above in line 5, ``AddUserSignal()`` is used to define the new custom signal ``YourSignal``.
|
||||
In line 10 ``EmitSignal()`` is used to emit that custom signal on every frame in ``_Process()``.
|
||||
|
||||
Make sure that ``AddUserSignal()`` is always executed before any calls using that signal (``EmitSignal()`` and ``Connect()``).
|
||||
If you are using both ``AddUserSignal()`` and ``Connect()`` or ``EmitSignal()`` in ``_Ready()``, this is especially important as load order of your node may change,
|
||||
and thus the order in which your various ``_Ready()`` functions are called.
|
||||
BIN
getting_started/scripting/c_sharp/img/attachcsharpscript.png
Normal file
BIN
getting_started/scripting/c_sharp/img/attachcsharpscript.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.9 KiB |
12
getting_started/scripting/c_sharp/index.rst
Normal file
12
getting_started/scripting/c_sharp/index.rst
Normal file
@@ -0,0 +1,12 @@
|
||||
C#
|
||||
===
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 1
|
||||
:name: toc-learn-scripting-C#
|
||||
|
||||
c_sharp_basics
|
||||
c_sharp_features
|
||||
c_sharp_differences
|
||||
|
||||
|
||||
Reference in New Issue
Block a user