Update & fix C# blocks under tutorials/scripting/

- `_Process` and `_PhysicsProcess` take their delta argument as a `double`
- Use string interpolation instead of concatenating strings
- Use `string` instead of `String` (`using System` was removed from everywhere in a previous PR)
- Use `System.Array.Empty<T>()` to init empty arrays
- Use `SignalName.*` instead of `nameof(*)` for signals
- Do not use `event` as an argument name (that's a keyword)
- Match node paths to screenshots when retrieving nodes from the tree
- Add a C# example for scene unique nodes
- Update the "Cross language scripting" page
- Add a note about using `is` against `null`
This commit is contained in:
Paul Joannon
2023-01-13 17:47:08 +01:00
parent c5f066b27e
commit ac22d6e537
12 changed files with 59 additions and 67 deletions

View File

@@ -16,11 +16,7 @@ The following two scripts will be used as references throughout this page.
extends Node
var str1 : String = "foo"
var str2 : String setget ,get_str2
func get_str2() -> String:
return "foofoo"
var my_field : String = "foo"
func print_node_name(node : Node) -> void:
print(node.get_name())
@@ -39,23 +35,22 @@ The following two scripts will be used as references throughout this page.
public partial class MyCSharpNode : Node
{
public String str1 = "bar";
public String str2 { get { return "barbar"; } }
public string myField = "bar";
public void PrintNodeName(Node node)
{
GD.Print(node.GetName());
GD.Print(node.Name);
}
public void PrintArray(String[] arr)
public void PrintArray(string[] arr)
{
foreach (String element in arr)
foreach (string element in arr)
{
GD.Print(element);
}
}
public void PrintNTimes(String msg, int n)
public void PrintNTimes(string msg, int n)
{
for (int i = 0; i < n; ++i)
{
@@ -77,7 +72,7 @@ Using C# from GDScript doesn't need much work. Once loaded
(see :ref:`doc_gdscript_classes_as_resources`), the script can be instantiated
with :ref:`new() <class_CSharpScript_method_new>`.
::
.. code-block:: gdscript
var my_csharp_script = load("res://path_to_cs_file.cs")
var my_csharp_node = my_csharp_script.new()
@@ -91,7 +86,7 @@ with :ref:`new() <class_CSharpScript_method_new>`.
``Invalid call. Nonexistent function `new` in base``.
For example, MyCoolNode.cs should contain a class named MyCoolNode.
The C# class needs to derive a Godot class, for example ``Godot.Object``.
Otherwise, the same error will occur.
@@ -121,18 +116,11 @@ Accessing C# fields from GDScript
Accessing C# fields from GDScript is straightforward, you shouldn't have
anything to worry about.
::
.. code-block:: gdscript
print(my_csharp_node.str1) # bar
my_csharp_node.str1 = "BAR"
print(my_csharp_node.str1) # BAR
print(my_csharp_node.str2) # barbar
# my_csharp_node.str2 = "BARBAR" # This line will hang and crash
Note that it doesn't matter if the field is defined as a property or an
attribute. However, trying to set a value on a property that does not define
a setter will result in a crash.
print(my_csharp_node.myField) # bar
my_csharp_node.myField = "BAR"
print(my_csharp_node.myField) # BAR
Accessing GDScript fields from C#
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -143,12 +131,9 @@ and :ref:`Object.Set() <class_Object_method_set>`. The first argument is the nam
.. code-block:: csharp
GD.Print(myGDScriptNode.Get("str1")); // foo
myGDScriptNode.Set("str1", "FOO");
GD.Print(myGDScriptNode.Get("str1")); // FOO
GD.Print(myGDScriptNode.Get("str2")); // foofoo
// myGDScriptNode.Set("str2", "FOOFOO"); // This line won't do anything
GD.Print(myGDScriptNode.Get("my_field")); // foo
myGDScriptNode.Set("my_field", "FOO");
GD.Print(myGDScriptNode.Get("my_field")); // FOO
Keep in mind that when setting a field value you should only use types the
GDScript side knows about.
@@ -165,7 +150,7 @@ marshalling process will do its best to cast the arguments to match
function signatures.
If that's impossible, you'll see the following error: ``Invalid call. Nonexistent function `FunctionName```.
::
.. code-block:: gdscript
my_csharp_node.PrintNodeName(self) # myGDScriptNode
# my_csharp_node.PrintNodeName() # This line will fail.
@@ -190,12 +175,9 @@ to said method.
myGDScriptNode.Call("print_n_times", "Hello there!", 2); // Hello there! Hello there!
// When dealing with functions taking a single array as arguments, we need to be careful.
// If we don't cast it into an object, the engine will treat each element of the array as a separate argument and the call will fail.
String[] arr = new String[] { "a", "b", "c" };
// myGDScriptNode.Call("print_array", arr); // This line will fail silently and won't error out.
myGDScriptNode.Call("print_array", (object)arr); // a, b, c
myGDScriptNode.Call("print_array", (object)new int[] { 1, 2, 3 }); // 1, 2, 3
string[] arr = new string[] { "a", "b", "c" };
myGDScriptNode.Call("print_array", arr); // a, b, c
myGDScriptNode.Call("print_array", new int[] { 1, 2, 3 }); // 1, 2, 3
// Note how the type of each array entry does not matter as long as it can be handled by the marshaller
.. warning::