Add missing C# code examples to documentation

Co-authored-by: A Thousand Ships <96648715+AThousandShips@users.noreply.github.com>
Co-authored-by: Raul Santos <raulsntos@gmail.com>
This commit is contained in:
Shawn Hardern
2024-08-25 12:12:49 +01:00
parent 6b1bd26c12
commit e09439a4e0
17 changed files with 1385 additions and 27 deletions

View File

@@ -25,22 +25,38 @@ Scene tree
Interacting with the active scene tree is **NOT** thread-safe. Make sure to use mutexes when sending data between threads. If you want to call functions from a thread, the *call_deferred* function may be used:
::
.. tabs::
.. code-tab:: gdscript
# Unsafe:
node.add_child(child_node)
# Safe:
node.add_child.call_deferred(child_node)
.. code-tab:: csharp
// Unsafe:
node.AddChild(childNode);
// Safe:
node.CallDeferred(Node.MethodName.AddChild, childNode);
However, creating scene chunks (nodes in tree arrangement) outside the active tree is fine. This way, parts of a scene can be built or instantiated in a thread, then added in the main thread:
::
.. tabs::
.. code-tab:: gdscript
var enemy_scene = load("res://enemy_scene.scn")
var enemy = enemy_scene.instantiate()
enemy.add_child(weapon) # Set a weapon.
world.add_child.call_deferred(enemy)
.. code-tab:: csharp
PackedScene enemyScene = GD.Load<PackedScene>("res://EnemyScene.scn");
Node enemy = enemyScene.Instantiate<Node>();
enemy.AddChild(weapon);
world.CallDeferred(Node.MethodName.AddChild, enemy);
Still, this is only really useful if you have **one** thread loading data.
Attempting to load or create scene chunks from multiple threads may work, but you risk
resources (which are only loaded once in Godot) tweaked by the multiple
@@ -61,7 +77,7 @@ Note that the Multi-Threaded thread model has several known bugs, so it may not
in all scenarios.
You should avoid calling functions involving direct interaction with the GPU on other threads, such as creating new textures
or modifying and retrieving image data, these operations can lead to performance stalls because they require synchronization
or modifying and retrieving image data, these operations can lead to performance stalls because they require synchronization
with the :ref:`RenderingServer<class_RenderingServer>`, as data needs to be transmitted to or updated on the GPU.
GDScript arrays, dictionaries

View File

@@ -252,6 +252,41 @@ and moves a :ref:`CanvasItem <class_CanvasItem>` when the body moves.
# if you have many bodies and a single callback.
Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)
.. code-tab:: csharp
using Godot;
public partial class MyNode2D : Node2D
{
private Rid _canvasItem;
private void BodyMoved(PhysicsDirectBodyState2D state, int index)
{
RenderingServer.CanvasItemSetTransform(_canvasItem, state.Transform);
}
public override void _Ready()
{
// Create the body.
var body = PhysicsServer2D.BodyCreate();
PhysicsServer2D.BodySetMode(body, PhysicsServer2D.BodyMode.Rigid);
// Add a shape.
var shape = PhysicsServer2D.RectangleShapeCreate();
// Set rectangle extents.
PhysicsServer2D.ShapeSetData(shape, new Vector2(10, 10));
// Make sure to keep the shape reference!
PhysicsServer2D.BodyAddShape(body, shape);
// Set space, so it collides in the same space as current scene.
PhysicsServer2D.BodySetSpace(body, GetWorld2D().Space);
// Move initial position.
PhysicsServer2D.BodySetState(body, PhysicsServer2D.BodyState.Transform, new Transform2D(0, new Vector2(10, 20)));
// Add the transform callback, when body moves
// The last parameter is optional, can be used as index
// if you have many bodies and a single callback.
PhysicsServer2D.BodySetForceIntegrationCallback(body, new Callable(this, MethodName.BodyMoved), 0);
}
}
The 3D version should be very similar, as 2D and 3D physics servers are identical (using
:ref:`RigidBody3D <class_RigidBody3D>` and :ref:`PhysicsServer3D <class_PhysicsServer3D>` respectively).