Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add missing C# code examples to documentation #9833

Merged
merged 1 commit into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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