Skip to content

Commit

Permalink
Merge pull request #9833 from ShawnHardern/update-csharp-docs
Browse files Browse the repository at this point in the history
Add missing C# code examples to documentation
  • Loading branch information
AThousandShips authored Aug 28, 2024
2 parents 586a2fd + e09439a commit d459bb9
Show file tree
Hide file tree
Showing 17 changed files with 1,385 additions and 27 deletions.
10 changes: 9 additions & 1 deletion about/introduction.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,19 @@
Introduction
============

::
.. tabs::
.. code-tab:: gdscript

func _ready():
print("Hello world!")

.. code-tab:: csharp

public override void _Ready()
{
GD.Print("Hello world!");
}

Welcome to the official documentation of **Godot Engine**, the free and open source
community-driven 2D and 3D game engine! Behind this mouthful, you will find a
powerful yet user-friendly tool that you can use to develop any kind of game,
Expand Down
38 changes: 33 additions & 5 deletions tutorials/i18n/internationalizing_games.rst
Original file line number Diff line number Diff line change
Expand Up @@ -75,11 +75,17 @@ Translate** in the inspector.
In code, the :ref:`Object.tr() <class_Object_method_tr>` function can be used.
This will just look up the text in the translations and convert it if found:

::
.. tabs::
.. code-tab:: gdscript

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

.. code-tab:: csharp

level.Text = Tr("LEVEL_5_NAME");
status.Text = Tr($"GAME_STATUS_{statusIndex}");

.. note::

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

::
.. tabs::
.. code-tab:: gdscript

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

::
.. tabs::
.. code-tab:: gdscript

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

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

.. code-tab:: csharp

// "Close", as in an action (to close something).
GetNode<Button>("Button").Text = Tr("Close", "Actions");

// "Close", as in a distance (opposite of "far").
GetNode<Label>("Distance").Text = Tr("Close", "Distance");

Pluralization
^^^^^^^^^^^^^

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

::
.. tabs::
.. code-tab:: gdscript

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

.. code-tab:: csharp

int numApples = 5;
GetNode<Label>("Label").Text = string.Format(TrN("There is {0} apple", "There are {0} apples", numApples), numApples);

This can be combined with a context if needed:

::
.. tabs::
.. code-tab:: gdscript

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

.. code-tab:: csharp

int numJobs = 1;
GetNode<Label>("Label").Text = string.Format(TrN("{0} job", "{0} jobs", numJobs, "Task Manager"), numJobs);

.. note::

Providing pluralized translations is only supported with
Expand Down
162 changes: 154 additions & 8 deletions tutorials/io/runtime_file_loading_and_saving.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ Plain text and binary files
Godot's :ref:`class_FileAccess` class provides methods to access files on the
filesystem for reading and writing:

::
.. tabs::
.. code-tab:: gdscript

func save_file(content):
func save_file(content):
var file = FileAccess.open("/path/to/file.txt", FileAccess.WRITE)
file.store_string(content)

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

.. code-tab:: csharp

private void SaveFile(string content)
{
using var file = FileAccess.Open("/Path/To/File.txt", FileAccess.ModeFlags.Write);
file.StoreString(content);
}

private string LoadFile()
{
using var file = FileAccess.Open("/Path/To/File.txt", FileAccess.ModeFlags.Read);
string content = file.GetAsText();
return content;
}

To handle custom binary formats (such as loading file formats not supported by
Godot), :ref:`class_FileAccess` provides several methods to read/write integers,
floats, strings and more. These FileAccess methods have names that start with
Expand Down Expand Up @@ -116,7 +132,8 @@ increase performance by reducing I/O utilization.
Example of loading an image and displaying it in a :ref:`class_TextureRect` node
(which requires conversion to :ref:`class_ImageTexture`):

::
.. tabs::
.. code-tab:: gdscript

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

.. code-tab:: csharp

// Load an image of any format supported by Godot from the filesystem.
var image = Image.LoadFromFile(path);
// Optionally, generate mipmaps if displaying the texture on a 3D surface
// so that the texture doesn't look grainy when viewed at a distance.
// image.GenerateMipmaps();
GetNode<TextureRect>("TextureRect").Texture = ImageTexture.CreateFromImage(image);

// Save the loaded Image to a PNG image.
image.SavePng("/Path/To/File.png");

// Save the converted ImageTexture to a PNG image.
GetNode<TextureRect>("TextureRect").Texture.GetImage().SavePng("/Path/To/File.png");

.. _doc_runtime_file_loading_and_saving_audio_video_files:

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

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

::
.. tabs::
.. code-tab:: gdscript

$AudioStreamPlayer.stream = AudioStreamOggVorbis.load_from_file(path)

.. code-tab:: csharp

GetNode<AudioStreamPlayer>("AudioStreamPlayer").Stream = AudioStreamOggVorbis.LoadFromFile(path);

Example of loading an Ogg Theora video file in a :ref:`class_VideoStreamPlayer` node:

::
.. tabs::
.. code-tab:: gdscript

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

.. code-tab:: csharp

var videoStreamTheora = new VideoStreamTheora();
// File extension is ignored, so it is possible to load Ogg Theora videos
// that have an `.ogg` extension this way.
videoStreamTheora.File = "/Path/To/File.ogv";
GetNode<VideoStreamPlayer>("VideoStreamPlayer").Stream = videoStreamTheora;

// VideoStreamPlayer's Autoplay property won't work if the stream is empty
// before this property is set, so call `Play()` after setting `Stream`.
GetNode<VideoStreamPlayer>("VideoStreamPlayer").Play();

.. note::

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

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

::
.. tabs::
.. code-tab:: gdscript

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

.. code-tab:: csharp

// Load an existing glTF scene.
// GLTFState is used by GLTFDocument to store the loaded scene's state.
// GLTFDocument is the class that handles actually loading glTF data into a Godot node tree,
// which means it supports glTF features such as lights and cameras.
var gltfDocumentLoad = new GltfDocument();
var gltfStateLoad = new GltfState();
var error = gltfDocumentLoad.AppendFromFile("/Path/To/File.gltf", gltfStateLoad);
if (error == Error.Ok)
{
var gltfSceneRootNode = gltfDocumentLoad.GenerateScene(gltfStateLoad);
AddChild(gltfSceneRootNode);
}
else
{
GD.PrintErr($"Couldn't load glTF scene (error code: {error}).");
}

// Save a new glTF scene.
var gltfDocumentSave = new GltfDocument();
var gltfStateSave = new GltfState();
gltfDocumentSave.AppendFromScene(gltfSceneRootNode, gltfStateSave);
// The file extension in the output `path` (`.gltf` or `.glb`) determines
// whether the output uses text or binary format.
// `GltfDocument.GenerateBuffer()` is also available for saving to memory.
gltfDocumentSave.WriteToFilesystem(gltfStateSave, path);

.. note::

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

::
.. tabs::
.. code-tab:: gdscript

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

.. code-tab:: csharp

string path = "/Path/To/Font.ttf";
var fontFile = new FontFile();

if (
path.EndsWith(".ttf", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".otf", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".woff", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".woff2", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".pfb", StringComparison.OrdinalIgnoreCase)
|| path.EndsWith(".pfm", StringComparison.OrdinalIgnoreCase)
)
{
fontFile.LoadDynamicFont(path);
}
else if (path.EndsWith(".fnt", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".font", StringComparison.OrdinalIgnoreCase))
{
fontFile.LoadBitmapFont(path);
}
else
{
GD.PrintErr("Invalid font file format.");
}

if (!fontFile.Data.IsEmpty())
{
// If font was loaded successfully, add it as a theme override.
GetNode<Label>("Label").AddThemeFontOverride("font", fontFile);
}

ZIP archives
------------

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

::
.. tabs::
.. code-tab:: gdscript

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

zip_packer.close()

.. code-tab:: csharp

// Load an existing ZIP archive.
var zipReader = new ZipReader();
zipReader.Open(path);
string[] files = zipReader.GetFiles();
// The list of files isn't sorted by default. Sort it for more consistent processing.
Array.Sort(files);
foreach (string file in files)
{
GetNode<ItemList>("ItemList").AddItem(file);
// Make folders disabled in the list.
GetNode<ItemList>("ItemList").SetItemDisabled(-1, file.EndsWith('/'));
}

// Save a new ZIP archive.
var zipPacker = new ZipPacker();
var error = zipPacker.Open(path);
if (error != Error.Ok)
{
GD.PrintErr($"Couldn't open path for saving ZIP archive (error code: {error}).");
return;
}

// Reuse the above ZIPReader instance to read files from an existing ZIP archive.
foreach (string file in zipReader.GetFiles())
{
zipPacker.StartFile(file);
zipPacker.WriteFile(zipReader.ReadFile(file));
zipPacker.CloseFile();
}

zipPacker.Close();
28 changes: 28 additions & 0 deletions tutorials/navigation/navigation_connecting_navmesh.rst
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,20 @@ The edge connection margin value of any navigation map can also be changed at ru
var default_map_rid: RID = get_world_2d().get_navigation_map()
NavigationServer2D.map_set_edge_connection_margin(default_map_rid, 50.0)

.. code-tab:: csharp 2D C#

using Godot;

public partial class MyNode2D : Node2D
{
public override void _Ready()
{
// 2D margins are designed to work with 2D "pixel" values.
Rid defaultMapRid = GetWorld2D().NavigationMap;
NavigationServer2D.MapSetEdgeConnectionMargin(defaultMapRid, 50.0f);
}
}

.. code-tab:: gdscript 3D GDScript

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

.. code-tab:: csharp 3D C#

using Godot;

public partial class MyNode3D : Node3D
{
public override void _Ready()
{
// 3D margins are designed to work with 3D world unit values.
Rid defaultMapRid = GetWorld3D().NavigationMap;
NavigationServer3D.MapSetEdgeConnectionMargin(defaultMapRid, 0.5f);
}
}

.. note::

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

0 comments on commit d459bb9

Please sign in to comment.