Skip to content

Commit d459bb9

Browse files
Merge pull request #9833 from ShawnHardern/update-csharp-docs
Add missing C# code examples to documentation
2 parents 586a2fd + e09439a commit d459bb9

17 files changed

+1385
-27
lines changed

about/introduction.rst

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,19 @@
55
Introduction
66
============
77

8-
::
8+
.. tabs::
9+
.. code-tab:: gdscript
910

1011
func _ready():
1112
print("Hello world!")
1213

14+
.. code-tab:: csharp
15+
16+
public override void _Ready()
17+
{
18+
GD.Print("Hello world!");
19+
}
20+
1321
Welcome to the official documentation of **Godot Engine**, the free and open source
1422
community-driven 2D and 3D game engine! Behind this mouthful, you will find a
1523
powerful yet user-friendly tool that you can use to develop any kind of game,

tutorials/i18n/internationalizing_games.rst

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,17 @@ Translate** in the inspector.
7575
In code, the :ref:`Object.tr() <class_Object_method_tr>` function can be used.
7676
This will just look up the text in the translations and convert it if found:
7777

78-
::
78+
.. tabs::
79+
.. code-tab:: gdscript
7980

8081
level.text = tr("LEVEL_5_NAME")
8182
status.text = tr("GAME_STATUS_%d" % status_index)
8283

84+
.. code-tab:: csharp
85+
86+
level.Text = Tr("LEVEL_5_NAME");
87+
status.Text = Tr($"GAME_STATUS_{statusIndex}");
88+
8389
.. note::
8490

8591
If no text is displayed after changing the language, try to use a different
@@ -105,7 +111,8 @@ allows translations to sound more natural. Named placeholders with the
105111
``String.format()`` function should be used whenever possible, as they also
106112
allow translators to choose the *order* in which placeholders appear:
107113

108-
::
114+
.. tabs::
115+
.. code-tab:: gdscript
109116

110117
# The placeholder's locations can be changed, but not their order.
111118
# This will probably not suffice for some target languages.
@@ -125,14 +132,23 @@ optionally specify a *translation context* to resolve this ambiguity and allow
125132
target languages to use different strings, even though the source string is
126133
identical:
127134

128-
::
135+
.. tabs::
136+
.. code-tab:: gdscript
129137

130138
# "Close", as in an action (to close something).
131139
button.set_text(tr("Close", "Actions"))
132140

133141
# "Close", as in a distance (opposite of "far").
134142
distance_label.set_text(tr("Close", "Distance"))
135143

144+
.. code-tab:: csharp
145+
146+
// "Close", as in an action (to close something).
147+
GetNode<Button>("Button").Text = Tr("Close", "Actions");
148+
149+
// "Close", as in a distance (opposite of "far").
150+
GetNode<Label>("Distance").Text = Tr("Close", "Distance");
151+
136152
Pluralization
137153
^^^^^^^^^^^^^
138154

@@ -148,18 +164,30 @@ Pluralization is meant to be used with positive (or zero) integer numbers only.
148164
Negative and floating-point values usually represent physical entities for which
149165
singular and plural don't clearly apply.
150166

151-
::
167+
.. tabs::
168+
.. code-tab:: gdscript
152169

153170
var num_apples = 5
154171
label.text = tr_n("There is %d apple", "There are %d apples", num_apples) % num_apples
155172

173+
.. code-tab:: csharp
174+
175+
int numApples = 5;
176+
GetNode<Label>("Label").Text = string.Format(TrN("There is {0} apple", "There are {0} apples", numApples), numApples);
177+
156178
This can be combined with a context if needed:
157179

158-
::
180+
.. tabs::
181+
.. code-tab:: gdscript
159182

160183
var num_jobs = 1
161184
label.text = tr_n("%d job", "%d jobs", num_jobs, "Task Manager") % num_jobs
162185

186+
.. code-tab:: csharp
187+
188+
int numJobs = 1;
189+
GetNode<Label>("Label").Text = string.Format(TrN("{0} job", "{0} jobs", numJobs, "Task Manager"), numJobs);
190+
163191
.. note::
164192

165193
Providing pluralized translations is only supported with

tutorials/io/runtime_file_loading_and_saving.rst

Lines changed: 154 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ Plain text and binary files
4545
Godot's :ref:`class_FileAccess` class provides methods to access files on the
4646
filesystem for reading and writing:
4747

48-
::
48+
.. tabs::
49+
.. code-tab:: gdscript
4950

50-
func save_file(content):
51+
func save_file(content):
5152
var file = FileAccess.open("/path/to/file.txt", FileAccess.WRITE)
5253
file.store_string(content)
5354

@@ -56,6 +57,21 @@ filesystem for reading and writing:
5657
var content = file.get_as_text()
5758
return content
5859

60+
.. code-tab:: csharp
61+
62+
private void SaveFile(string content)
63+
{
64+
using var file = FileAccess.Open("/Path/To/File.txt", FileAccess.ModeFlags.Write);
65+
file.StoreString(content);
66+
}
67+
68+
private string LoadFile()
69+
{
70+
using var file = FileAccess.Open("/Path/To/File.txt", FileAccess.ModeFlags.Read);
71+
string content = file.GetAsText();
72+
return content;
73+
}
74+
5975
To handle custom binary formats (such as loading file formats not supported by
6076
Godot), :ref:`class_FileAccess` provides several methods to read/write integers,
6177
floats, strings and more. These FileAccess methods have names that start with
@@ -116,7 +132,8 @@ increase performance by reducing I/O utilization.
116132
Example of loading an image and displaying it in a :ref:`class_TextureRect` node
117133
(which requires conversion to :ref:`class_ImageTexture`):
118134

119-
::
135+
.. tabs::
136+
.. code-tab:: gdscript
120137

121138
# Load an image of any format supported by Godot from the filesystem.
122139
var image = Image.load_from_file(path)
@@ -131,6 +148,21 @@ Example of loading an image and displaying it in a :ref:`class_TextureRect` node
131148
# Save the converted ImageTexture to a PNG image.
132149
$TextureRect.texture.get_image().save_png("/path/to/file.png")
133150

151+
.. code-tab:: csharp
152+
153+
// Load an image of any format supported by Godot from the filesystem.
154+
var image = Image.LoadFromFile(path);
155+
// Optionally, generate mipmaps if displaying the texture on a 3D surface
156+
// so that the texture doesn't look grainy when viewed at a distance.
157+
// image.GenerateMipmaps();
158+
GetNode<TextureRect>("TextureRect").Texture = ImageTexture.CreateFromImage(image);
159+
160+
// Save the loaded Image to a PNG image.
161+
image.SavePng("/Path/To/File.png");
162+
163+
// Save the converted ImageTexture to a PNG image.
164+
GetNode<TextureRect>("TextureRect").Texture.GetImage().SavePng("/Path/To/File.png");
165+
134166
.. _doc_runtime_file_loading_and_saving_audio_video_files:
135167

136168
Audio/video files
@@ -143,13 +175,19 @@ load correctly as audio files in Godot.
143175

144176
Example of loading an Ogg Vorbis audio file in an :ref:`class_AudioStreamPlayer` node:
145177

146-
::
178+
.. tabs::
179+
.. code-tab:: gdscript
147180

148181
$AudioStreamPlayer.stream = AudioStreamOggVorbis.load_from_file(path)
149182

183+
.. code-tab:: csharp
184+
185+
GetNode<AudioStreamPlayer>("AudioStreamPlayer").Stream = AudioStreamOggVorbis.LoadFromFile(path);
186+
150187
Example of loading an Ogg Theora video file in a :ref:`class_VideoStreamPlayer` node:
151188

152-
::
189+
.. tabs::
190+
.. code-tab:: gdscript
153191

154192
var video_stream_theora = VideoStreamTheora.new()
155193
# File extension is ignored, so it is possible to load Ogg Theora videos
@@ -161,6 +199,18 @@ Example of loading an Ogg Theora video file in a :ref:`class_VideoStreamPlayer`
161199
# before this property is set, so call `play()` after setting `stream`.
162200
$VideoStreamPlayer.play()
163201

202+
.. code-tab:: csharp
203+
204+
var videoStreamTheora = new VideoStreamTheora();
205+
// File extension is ignored, so it is possible to load Ogg Theora videos
206+
// that have an `.ogg` extension this way.
207+
videoStreamTheora.File = "/Path/To/File.ogv";
208+
GetNode<VideoStreamPlayer>("VideoStreamPlayer").Stream = videoStreamTheora;
209+
210+
// VideoStreamPlayer's Autoplay property won't work if the stream is empty
211+
// before this property is set, so call `Play()` after setting `Stream`.
212+
GetNode<VideoStreamPlayer>("VideoStreamPlayer").Play();
213+
164214
.. note::
165215

166216
Godot doesn't support runtime loading of MP3 or WAV files yet. Until this is
@@ -185,7 +235,8 @@ as it's faster to write and smaller, but the text format is easier to debug.
185235

186236
Example of loading a glTF scene and appending its root node to the scene:
187237

188-
::
238+
.. tabs::
239+
.. code-tab:: gdscript
189240

190241
# Load an existing glTF scene.
191242
# GLTFState is used by GLTFDocument to store the loaded scene's state.
@@ -209,6 +260,34 @@ Example of loading a glTF scene and appending its root node to the scene:
209260
# `GLTFDocument.generate_buffer()` is also available for saving to memory.
210261
gltf_document_save.write_to_filesystem(gltf_state_save, path)
211262

263+
.. code-tab:: csharp
264+
265+
// Load an existing glTF scene.
266+
// GLTFState is used by GLTFDocument to store the loaded scene's state.
267+
// GLTFDocument is the class that handles actually loading glTF data into a Godot node tree,
268+
// which means it supports glTF features such as lights and cameras.
269+
var gltfDocumentLoad = new GltfDocument();
270+
var gltfStateLoad = new GltfState();
271+
var error = gltfDocumentLoad.AppendFromFile("/Path/To/File.gltf", gltfStateLoad);
272+
if (error == Error.Ok)
273+
{
274+
var gltfSceneRootNode = gltfDocumentLoad.GenerateScene(gltfStateLoad);
275+
AddChild(gltfSceneRootNode);
276+
}
277+
else
278+
{
279+
GD.PrintErr($"Couldn't load glTF scene (error code: {error}).");
280+
}
281+
282+
// Save a new glTF scene.
283+
var gltfDocumentSave = new GltfDocument();
284+
var gltfStateSave = new GltfState();
285+
gltfDocumentSave.AppendFromScene(gltfSceneRootNode, gltfStateSave);
286+
// The file extension in the output `path` (`.gltf` or `.glb`) determines
287+
// whether the output uses text or binary format.
288+
// `GltfDocument.GenerateBuffer()` is also available for saving to memory.
289+
gltfDocumentSave.WriteToFilesystem(gltfStateSave, path);
290+
212291
.. note::
213292

214293
When loading a glTF scene, a *base path* must be set so that external
@@ -240,7 +319,8 @@ Godot's support for :ref:`doc_using_fonts_system_fonts`.
240319
Example of loading a font file automatically according to its file extension,
241320
then adding it as a theme override to a :ref:`class_Label` node:
242321

243-
::
322+
.. tabs::
323+
.. code-tab:: gdscript
244324

245325
var path = "/path/to/font.ttf"
246326
var path_lower = path.to_lower()
@@ -263,6 +343,37 @@ then adding it as a theme override to a :ref:`class_Label` node:
263343
# If font was loaded successfully, add it as a theme override.
264344
$Label.add_theme_font_override("font", font_file)
265345

346+
.. code-tab:: csharp
347+
348+
string path = "/Path/To/Font.ttf";
349+
var fontFile = new FontFile();
350+
351+
if (
352+
path.EndsWith(".ttf", StringComparison.OrdinalIgnoreCase)
353+
|| path.EndsWith(".otf", StringComparison.OrdinalIgnoreCase)
354+
|| path.EndsWith(".woff", StringComparison.OrdinalIgnoreCase)
355+
|| path.EndsWith(".woff2", StringComparison.OrdinalIgnoreCase)
356+
|| path.EndsWith(".pfb", StringComparison.OrdinalIgnoreCase)
357+
|| path.EndsWith(".pfm", StringComparison.OrdinalIgnoreCase)
358+
)
359+
{
360+
fontFile.LoadDynamicFont(path);
361+
}
362+
else if (path.EndsWith(".fnt", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".font", StringComparison.OrdinalIgnoreCase))
363+
{
364+
fontFile.LoadBitmapFont(path);
365+
}
366+
else
367+
{
368+
GD.PrintErr("Invalid font file format.");
369+
}
370+
371+
if (!fontFile.Data.IsEmpty())
372+
{
373+
// If font was loaded successfully, add it as a theme override.
374+
GetNode<Label>("Label").AddThemeFontOverride("font", fontFile);
375+
}
376+
266377
ZIP archives
267378
------------
268379

@@ -285,7 +396,8 @@ through the Godot editor to generate PCK/ZIP files.
285396
Example that lists files in a ZIP archive in an :ref:`class_ItemList` node,
286397
then writes contents read from it to a new ZIP archive (essentially duplicating the archive):
287398

288-
::
399+
.. tabs::
400+
.. code-tab:: gdscript
289401

290402
# Load an existing ZIP archive.
291403
var zip_reader = ZIPReader.new()
@@ -312,3 +424,37 @@ then writes contents read from it to a new ZIP archive (essentially duplicating
312424
zip_packer.close_file()
313425

314426
zip_packer.close()
427+
428+
.. code-tab:: csharp
429+
430+
// Load an existing ZIP archive.
431+
var zipReader = new ZipReader();
432+
zipReader.Open(path);
433+
string[] files = zipReader.GetFiles();
434+
// The list of files isn't sorted by default. Sort it for more consistent processing.
435+
Array.Sort(files);
436+
foreach (string file in files)
437+
{
438+
GetNode<ItemList>("ItemList").AddItem(file);
439+
// Make folders disabled in the list.
440+
GetNode<ItemList>("ItemList").SetItemDisabled(-1, file.EndsWith('/'));
441+
}
442+
443+
// Save a new ZIP archive.
444+
var zipPacker = new ZipPacker();
445+
var error = zipPacker.Open(path);
446+
if (error != Error.Ok)
447+
{
448+
GD.PrintErr($"Couldn't open path for saving ZIP archive (error code: {error}).");
449+
return;
450+
}
451+
452+
// Reuse the above ZIPReader instance to read files from an existing ZIP archive.
453+
foreach (string file in zipReader.GetFiles())
454+
{
455+
zipPacker.StartFile(file);
456+
zipPacker.WriteFile(zipReader.ReadFile(file));
457+
zipPacker.CloseFile();
458+
}
459+
460+
zipPacker.Close();

tutorials/navigation/navigation_connecting_navmesh.rst

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,20 @@ The edge connection margin value of any navigation map can also be changed at ru
5353
var default_map_rid: RID = get_world_2d().get_navigation_map()
5454
NavigationServer2D.map_set_edge_connection_margin(default_map_rid, 50.0)
5555

56+
.. code-tab:: csharp 2D C#
57+
58+
using Godot;
59+
60+
public partial class MyNode2D : Node2D
61+
{
62+
public override void _Ready()
63+
{
64+
// 2D margins are designed to work with 2D "pixel" values.
65+
Rid defaultMapRid = GetWorld2D().NavigationMap;
66+
NavigationServer2D.MapSetEdgeConnectionMargin(defaultMapRid, 50.0f);
67+
}
68+
}
69+
5670
.. code-tab:: gdscript 3D GDScript
5771

5872
extends Node3D
@@ -62,6 +76,20 @@ The edge connection margin value of any navigation map can also be changed at ru
6276
var default_map_rid: RID = get_world_3d().get_navigation_map()
6377
NavigationServer3D.map_set_edge_connection_margin(default_map_rid, 0.5)
6478

79+
.. code-tab:: csharp 3D C#
80+
81+
using Godot;
82+
83+
public partial class MyNode3D : Node3D
84+
{
85+
public override void _Ready()
86+
{
87+
// 3D margins are designed to work with 3D world unit values.
88+
Rid defaultMapRid = GetWorld3D().NavigationMap;
89+
NavigationServer3D.MapSetEdgeConnectionMargin(defaultMapRid, 0.5f);
90+
}
91+
}
92+
6593
.. note::
6694

6795
Changing the edge connection margin will trigger a full update of all navigation mesh connections on the NavigationServer.

0 commit comments

Comments
 (0)