Merge pull request #40978 from HaSa1002/docs-code-1

Port code examples to C# of classes beginning with A and B
This commit is contained in:
Rémi Verschelde 2020-09-26 12:42:42 +02:00 committed by GitHub
commit 84cec777c1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 388 additions and 66 deletions

View file

@ -5,7 +5,8 @@
</brief_description>
<description>
This class provides access to AES encryption/decryption of raw data. Both AES-ECB and AES-CBC mode are supported.
[codeblock]
[codeblocks]
[gdscript]
extends Node
var aes = AESContext.new()
@ -35,7 +36,45 @@
aes.finish()
# Check CBC
assert(decrypted == data.to_utf8())
[/codeblock]
[/gdscript]
[csharp]
using Godot;
using System;
using System.Diagnostics;
public class Example : Node
{
public AESContext Aes = new AESContext();
public override void _Ready()
{
string key = "My secret key!!!"; // Key must be either 16 or 32 bytes.
string data = "My secret text!!"; // Data size must be multiple of 16 bytes, apply padding if needed.
// Encrypt ECB
Aes.Start(AESContext.Mode.EcbEncrypt, key.ToUTF8());
byte[] encrypted = Aes.Update(data.ToUTF8());
Aes.Finish();
// Decrypt ECB
Aes.Start(AESContext.Mode.EcbDecrypt, key.ToUTF8());
byte[] decrypted = Aes.Update(encrypted);
Aes.Finish();
// Check ECB
Debug.Assert(decrypted == data.ToUTF8());
string iv = "My secret iv!!!!"; // IV must be of exactly 16 bytes.
// Encrypt CBC
Aes.Start(AESContext.Mode.EcbEncrypt, key.ToUTF8(), iv.ToUTF8());
encrypted = Aes.Update(data.ToUTF8());
Aes.Finish();
// Decrypt CBC
Aes.Start(AESContext.Mode.EcbDecrypt, key.ToUTF8(), iv.ToUTF8());
decrypted = Aes.Update(encrypted);
Aes.Finish();
// Check CBC
Debug.Assert(decrypted == data.ToUTF8());
}
}
[/csharp]
[/codeblocks]
</description>
<tutorials>
</tutorials>

View file

@ -7,7 +7,8 @@
A* (A star) is a computer algorithm that is widely used in pathfinding and graph traversal, the process of plotting short paths among vertices (points), passing through a given set of edges (segments). It enjoys widespread use due to its performance and accuracy. Godot's A* implementation uses points in three-dimensional space and Euclidean distances by default.
You must add points manually with [method add_point] and create segments manually with [method connect_points]. Then you can test if there is a path between two points with the [method are_points_connected] function, get a path containing indices by [method get_id_path], or one containing actual coordinates with [method get_point_path].
It is also possible to use non-Euclidean distances. To do so, create a class that extends [code]AStar[/code] and override methods [method _compute_cost] and [method _estimate_cost]. Both take two indices and return a length, as is shown in the following example.
[codeblock]
[codeblocks]
[gdscript]
class MyAStar:
extends AStar
@ -16,7 +17,21 @@
func _estimate_cost(u, v):
return min(0, abs(u - v) - 1)
[/codeblock]
[/gdscript]
[csharp]
public class MyAStar : AStar
{
public override float _ComputeCost(int u, int v)
{
return Mathf.Abs(u - v);
}
public override float _EstimateCost(int u, int v)
{
return Mathf.Min(0, Mathf.Abs(u - v) - 1);
}
}
[/csharp]
[/codeblocks]
[method _estimate_cost] should return a lower bound of the distance, i.e. [code]_estimate_cost(u, v) &lt;= _compute_cost(u, v)[/code]. This serves as a hint to the algorithm because the custom [code]_compute_cost[/code] might be computation-heavy. If this is not the case, make [method _estimate_cost] return the same value as [method _compute_cost] to provide the algorithm with the most accurate information.
</description>
<tutorials>
@ -57,10 +72,16 @@
</argument>
<description>
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar.new()
astar.add_point(1, Vector3(1, 0, 0), 4) # Adds the point (1, 0, 0) with weight_scale 4 and id 1
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar();
astar.AddPoint(1, new Vector3(1, 0, 0), 4); // Adds the point (1, 0, 0) with weight_scale 4 and id 1
[/csharp]
[/codeblocks]
If there already exists a point for the given [code]id[/code], its position and weight scale are updated to the given values.
</description>
</method>
@ -95,12 +116,20 @@
</argument>
<description>
Creates a segment between the given points. If [code]bidirectional[/code] is [code]false[/code], only movement from [code]id[/code] to [code]to_id[/code] is allowed, not the reverse direction.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar.new()
astar.add_point(1, Vector3(1, 1, 0))
astar.add_point(2, Vector3(0, 5, 0))
astar.connect_points(1, 2, false)
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar();
astar.AddPoint(1, new Vector3(1, 1, 0));
astar.AddPoint(2, new Vector3(0, 5, 0));
astar.ConnectPoints(1, 2, false);
[/csharp]
[/codeblocks]
</description>
</method>
<method name="disconnect_points">
@ -142,13 +171,22 @@
</argument>
<description>
Returns the closest position to [code]to_position[/code] that resides inside a segment between two connected points.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar.new()
astar.add_point(1, Vector3(0, 0, 0))
astar.add_point(2, Vector3(0, 5, 0))
astar.connect_points(1, 2)
var res = astar.get_closest_position_in_segment(Vector3(3, 3, 0)) # Returns (0, 3, 0)
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar();
astar.AddPoint(1, new Vector3(0, 0, 0));
astar.AddPoint(2, new Vector3(0, 5, 0));
astar.ConnectPoints(1, 2);
Vector3 res = astar.GetClosestPositionInSegment(new Vector3(3, 3, 0)); // Returns (0, 3, 0)
[/csharp]
[/codeblocks]
The result is in the segment that goes from [code]y = 0[/code] to [code]y = 5[/code]. It's the closest position in the segment to the given point.
</description>
</method>
@ -161,7 +199,8 @@
</argument>
<description>
Returns an array with the IDs of the points that form the path found by AStar between the given points. The array is ordered from the starting point to the ending point of the path.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar.new()
astar.add_point(1, Vector3(0, 0, 0))
astar.add_point(2, Vector3(0, 1, 0), 1) # Default weight is 1
@ -174,7 +213,20 @@
astar.connect_points(1, 4, false)
var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar();
astar.AddPoint(1, new Vector3(0, 0, 0));
astar.AddPoint(2, new Vector3(0, 1, 0), 1); // Default weight is 1
astar.AddPoint(3, new Vector3(1, 1, 0));
astar.AddPoint(4, new Vector3(2, 0, 0));
astar.ConnectPoints(1, 2, false);
astar.ConnectPoints(2, 3, false);
astar.ConnectPoints(4, 3, false);
astar.ConnectPoints(1, 4, false);
int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
[/csharp]
[/codeblocks]
If you change the 2nd point's weight to 3, then the result will be [code][1, 4, 3][/code] instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2.
</description>
</method>
@ -192,7 +244,8 @@
</argument>
<description>
Returns an array with the IDs of the points that form the connection with the given point.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar.new()
astar.add_point(1, Vector3(0, 0, 0))
astar.add_point(2, Vector3(0, 1, 0))
@ -203,7 +256,19 @@
astar.connect_points(1, 3, true)
var neighbors = astar.get_point_connections(1) # Returns [2, 3]
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar();
astar.AddPoint(1, new Vector3(0, 0, 0));
astar.AddPoint(2, new Vector3(0, 1, 0));
astar.AddPoint(3, new Vector3(1, 1, 0));
astar.AddPoint(4, new Vector3(2, 0, 0));
astar.ConnectPoints(1, 2, true);
astar.ConnectPoints(1, 3, true);
int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
[/csharp]
[/codeblocks]
</description>
</method>
<method name="get_point_count" qualifiers="const">

View file

@ -44,10 +44,16 @@
</argument>
<description>
Adds a new point at the given position with the given identifier. The algorithm prefers points with lower [code]weight_scale[/code] to form a path. The [code]id[/code] must be 0 or larger, and the [code]weight_scale[/code] must be 1 or larger.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar2D.new()
astar.add_point(1, Vector2(1, 0), 4) # Adds the point (1, 0) with weight_scale 4 and id 1
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar2D();
astar.AddPoint(1, new Vector2(1, 0), 4); // Adds the point (1, 0) with weight_scale 4 and id 1
[/csharp]
[/codeblocks]
If there already exists a point for the given [code]id[/code], its position and weight scale are updated to the given values.
</description>
</method>
@ -80,12 +86,20 @@
</argument>
<description>
Creates a segment between the given points. If [code]bidirectional[/code] is [code]false[/code], only movement from [code]id[/code] to [code]to_id[/code] is allowed, not the reverse direction.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar2D.new()
astar.add_point(1, Vector2(1, 1))
astar.add_point(2, Vector2(0, 5))
astar.connect_points(1, 2, false)
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar2D();
astar.AddPoint(1, new Vector2(1, 1));
astar.AddPoint(2, new Vector2(0, 5));
astar.ConnectPoints(1, 2, false);
[/csharp]
[/codeblocks]
</description>
</method>
<method name="disconnect_points">
@ -125,13 +139,22 @@
</argument>
<description>
Returns the closest position to [code]to_position[/code] that resides inside a segment between two connected points.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar2D.new()
astar.add_point(1, Vector2(0, 0))
astar.add_point(2, Vector2(0, 5))
astar.connect_points(1, 2)
var res = astar.get_closest_position_in_segment(Vector2(3, 3)) # Returns (0, 3)
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar2D();
astar.AddPoint(1, new Vector2(0, 0));
astar.AddPoint(2, new Vector2(0, 5));
astar.ConnectPoints(1, 2);
Vector2 res = astar.GetClosestPositionInSegment(new Vector2(3, 3)); // Returns (0, 3)
[/csharp]
[/codeblocks]
The result is in the segment that goes from [code]y = 0[/code] to [code]y = 5[/code]. It's the closest position in the segment to the given point.
</description>
</method>
@ -144,7 +167,8 @@
</argument>
<description>
Returns an array with the IDs of the points that form the path found by AStar2D between the given points. The array is ordered from the starting point to the ending point of the path.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar2D.new()
astar.add_point(1, Vector2(0, 0))
astar.add_point(2, Vector2(0, 1), 1) # Default weight is 1
@ -157,7 +181,21 @@
astar.connect_points(1, 4, false)
var res = astar.get_id_path(1, 3) # Returns [1, 2, 3]
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar2D();
astar.AddPoint(1, new Vector2(0, 0));
astar.AddPoint(2, new Vector2(0, 1), 1); // Default weight is 1
astar.AddPoint(3, new Vector2(1, 1));
astar.AddPoint(4, new Vector2(2, 0));
astar.ConnectPoints(1, 2, false);
astar.ConnectPoints(2, 3, false);
astar.ConnectPoints(4, 3, false);
astar.ConnectPoints(1, 4, false);
int[] res = astar.GetIdPath(1, 3); // Returns [1, 2, 3]
[/csharp]
[/codeblocks]
If you change the 2nd point's weight to 3, then the result will be [code][1, 4, 3][/code] instead, because now even though the distance is longer, it's "easier" to get through point 4 than through point 2.
</description>
</method>
@ -175,7 +213,8 @@
</argument>
<description>
Returns an array with the IDs of the points that form the connection with the given point.
[codeblock]
[codeblocks]
[gdscript]
var astar = AStar2D.new()
astar.add_point(1, Vector2(0, 0))
astar.add_point(2, Vector2(0, 1))
@ -186,7 +225,20 @@
astar.connect_points(1, 3, true)
var neighbors = astar.get_point_connections(1) # Returns [2, 3]
[/codeblock]
[/gdscript]
[csharp]
var astar = new AStar2D();
astar.AddPoint(1, new Vector2(0, 0));
astar.AddPoint(2, new Vector2(0, 1));
astar.AddPoint(3, new Vector2(1, 1));
astar.AddPoint(4, new Vector2(2, 0));
astar.ConnectPoints(1, 2, true);
astar.ConnectPoints(1, 3, true);
int[] neighbors = astar.GetPointConnections(1); // Returns [2, 3]
[/csharp]
[/codeblocks]
</description>
</method>
<method name="get_point_count" qualifiers="const">

View file

@ -76,6 +76,7 @@
<signals>
<signal name="cancelled">
<description>
Emitted when the dialog is closed or the button created with [method add_cancel] is pressed.
</description>
</signal>
<signal name="confirmed">

View file

@ -5,7 +5,8 @@
</brief_description>
<description>
An Animation resource contains data used to animate everything in the engine. Animations are divided into tracks, and each track must be linked to a node. The state of that node can be changed through time, by adding timed keys (events) to the track.
[codeblock]
[codeblocks]
[gdscript]
# This creates an animation that makes the node "Enemy" move to the right by
# 100 pixels in 0.5 seconds.
var animation = Animation.new()
@ -13,7 +14,17 @@
animation.track_set_path(track_index, "Enemy:position:x")
animation.track_insert_key(track_index, 0.0, 0)
animation.track_insert_key(track_index, 0.5, 100)
[/codeblock]
[/gdscript]
[csharp]
// This creates an animation that makes the node "Enemy" move to the right by
// 100 pixels in 0.5 seconds.
var animation = new Animation();
int trackIndex = animation.AddTrack(Animation.TrackType.Value);
animation.TrackSetPath(trackIndex, "Enemy:position:x");
animation.TrackInsertKey(trackIndex, 0.0f, 0);
animation.TrackInsertKey(trackIndex, 0.5f, 100);
[/csharp]
[/codeblocks]
Animations are just data containers, and must be added to nodes such as an [AnimationPlayer] to be played back. Animation tracks have different types, each with its own set of dedicated methods. Check [enum TrackType] to see available types.
</description>
<tutorials>

View file

@ -6,10 +6,16 @@
<description>
Contains multiple nodes representing animation states, connected in a graph. Node transitions can be configured to happen automatically or via code, using a shortest-path algorithm. Retrieve the [AnimationNodeStateMachinePlayback] object from the [AnimationTree] node to control it programmatically.
[b]Example:[/b]
[codeblock]
[codeblocks]
[gdscript]
var state_machine = $AnimationTree.get("parameters/playback")
state_machine.travel("some_state")
[/codeblock]
[/gdscript]
[csharp]
var stateMachine = GetNode&lt;AnimationTree&gt;("AnimationTree").Get("parameters/playback") as AnimationNodeStateMachinePlayback;
stateMachine.Travel("some_state");
[/csharp]
[/codeblocks]
</description>
<tutorials>
<link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>

View file

@ -6,10 +6,16 @@
<description>
Allows control of [AnimationTree] state machines created with [AnimationNodeStateMachine]. Retrieve with [code]$AnimationTree.get("parameters/playback")[/code].
[b]Example:[/b]
[codeblock]
[codeblocks]
[gdscript]
var state_machine = $AnimationTree.get("parameters/playback")
state_machine.travel("some_state")
[/codeblock]
[/gdscript]
[csharp]
var stateMachine = GetNode&lt;AnimationTree&gt;("AnimationTree").Get("parameters/playback") as AnimationNodeStateMachinePlayback;
stateMachine.Travel("some_state");
[/csharp]
[/codeblocks]
</description>
<tutorials>
<link title="AnimationTree">https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html</link>

View file

@ -12,9 +12,14 @@
<members>
<member name="advance_condition" type="StringName" setter="set_advance_condition" getter="get_advance_condition" default="@&quot;&quot;">
Turn on auto advance when this condition is set. The provided name will become a boolean parameter on the [AnimationTree] that can be controlled from code (see [url=https://docs.godotengine.org/en/latest/tutorials/animation/animation_tree.html#controlling-from-code][/url]). For example, if [member AnimationTree.tree_root] is an [AnimationNodeStateMachine] and [member advance_condition] is set to [code]"idle"[/code]:
[codeblock]
$animation_tree["parameters/conditions/idle"] = is_on_floor and (linear_velocity.x == 0)
[/codeblock]
[codeblocks]
[gdscript]
$animation_tree.set("parameters/conditions/idle", is_on_floor and (linear_velocity.x == 0))
[/gdscript]
[csharp]
GetNode&lt;AnimationTree&gt;("animation_tree").Set("parameters/conditions/idle", IsOnFloor &amp;&amp; (LinearVelocity.x == 0));
[/csharp]
[/codeblocks]
</member>
<member name="auto_advance" type="bool" setter="set_auto_advance" getter="has_auto_advance" default="false">
Turn on the transition automatically when this state is reached. This works best with [constant SWITCH_MODE_AT_END].

View file

@ -6,20 +6,38 @@
<description>
Generic array which can contain several elements of any type, accessible by a numerical index starting at 0. Negative indices can be used to count from the back, like in Python (-1 is the last element, -2 the second to last, etc.).
[b]Example:[/b]
[codeblock]
[codeblocks]
[gdscript]
var array = ["One", 2, 3, "Four"]
print(array[0]) # One.
print(array[2]) # 3.
print(array[-1]) # Four.
array[2] = "Three"
print(array[-2]) # Three.
[/codeblock]
[/gdscript]
[csharp]
var array = new Godot.Collections.Array{"One", 2, 3, "Four"};
GD.Print(array[0]); // One.
GD.Print(array[2]); // 3.
GD.Print(array[array.Count - 1]); // Four.
array[2] = "Three";
GD.Print(array[array.Count - 2]); // Three.
[/csharp]
[/codeblocks]
Arrays can be concatenated using the [code]+[/code] operator:
[codeblock]
[codeblocks]
[gdscript]
var array1 = ["One", 2]
var array2 = [3, "Four"]
print(array1 + array2) # ["One", 2, 3, "Four"]
[/codeblock]
[/gdscript]
[csharp]
// Array concatenation is not possible with C# arrays, but is with Godot.Collections.Array.
var array1 = new Godot.Collections.Array("One", 2);
var array2 = new Godot.Collections.Array(3, "Four");
GD.Print(array1 + array2); // Prints [One, 2, 3, Four]
[/csharp]
[/codeblocks]
[b]Note:[/b] Arrays are always passed by reference. To get a copy of an array which can be modified independently of the original array, use [method duplicate].
</description>
<tutorials>
@ -228,18 +246,39 @@
</argument>
<description>
Returns [code]true[/code] if the array contains the given value.
[codeblock]
[codeblocks]
[gdscript]
print(["inside", 7].has("inside")) # True
print(["inside", 7].has("outside")) # False
print(["inside", 7].has(7)) # True
print(["inside", 7].has("7")) # False
[/codeblock]
[/gdscript]
[csharp]
var arr = new Godot.Collections.Array{"inside", 7};
// has is renamed to Contains
GD.Print(arr.Contains("inside")); // True
GD.Print(arr.Contains("outside")); // False
GD.Print(arr.Contains(7)); // True
GD.Print(arr.Contains("7")); // False
[/csharp]
[/codeblocks]
[b]Note:[/b] This is equivalent to using the [code]in[/code] operator as follows:
[codeblock]
[codeblocks]
[gdscript]
# Will evaluate to `true`.
if 2 in [2, 4, 6, 8]:
pass
[/codeblock]
print("Containes!")
[/gdscript]
[csharp]
// As there is no "in" keyword in C#, you have to use Contains
var array = new Godot.Collections.Array{2, 4, 6, 8};
if (array.Contains(2))
{
GD.Print("Containes!");
}
[/csharp]
[/codeblocks]
</description>
</method>
<method name="hash">
@ -377,11 +416,16 @@
<description>
Sorts the array.
[b]Note:[/b] Strings are sorted in alphabetical order (as opposed to natural order). This may lead to unexpected behavior when sorting an array of strings ending with a sequence of numbers. Consider the following example:
[codeblock]
[codeblocks]
[gdscript]
var strings = ["string1", "string2", "string10", "string11"]
strings.sort()
print(strings) # Prints [string1, string10, string11, string2]
[/codeblock]
[/gdscript]
[csharp]
// There is no sort support for Godot.Collections.Array
[/csharp]
[/codeblocks]
</description>
</method>
<method name="sort_custom">
@ -394,7 +438,8 @@
<description>
Sorts the array using a custom method. The arguments are an object that holds the method and the name of such method. The custom method receives two arguments (a pair of elements from the array) and must return either [code]true[/code] or [code]false[/code].
[b]Note:[/b] you cannot randomize the return value as the heapsort algorithm expects a deterministic result. Doing so will result in unexpected behavior.
[codeblock]
[codeblocks]
[gdscript]
class MyCustomSorter:
static func sort_ascending(a, b):
if a[0] &lt; b[0]:
@ -404,7 +449,11 @@
var my_items = [[5, "Potato"], [9, "Rice"], [4, "Tomato"]]
my_items.sort_custom(MyCustomSorter, "sort_ascending")
print(my_items) # Prints [[4, Tomato], [5, Potato], [9, Rice]].
[/codeblock]
[/gdscript]
[csharp]
// There is no custom sort support for Godot.Collections.Array
[/csharp]
[/codeblocks]
</description>
</method>
</methods>

View file

@ -6,21 +6,42 @@
<description>
The [ArrayMesh] is used to construct a [Mesh] by specifying the attributes as arrays.
The most basic example is the creation of a single triangle:
[codeblock]
[codeblocks]
[gdscript]
var vertices = PackedVector3Array()
vertices.push_back(Vector3(0, 1, 0))
vertices.push_back(Vector3(1, 0, 0))
vertices.push_back(Vector3(0, 0, 1))
# Initialize the ArrayMesh.
var arr_mesh = ArrayMesh.new()
var arrays = []
arrays.resize(ArrayMesh.ARRAY_MAX)
arrays[ArrayMesh.ARRAY_VERTEX] = vertices
# Create the Mesh.
arr_mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
var m = MeshInstance3D.new()
m.mesh = arr_mesh
[/codeblock]
[/gdscript]
[csharp]
var vertices = new Godot.Collections.Array&lt;Vector3&gt;();
vertices.Add(new Vector3(0, 1, 0));
vertices.Add(new Vector3(1, 0, 0));
vertices.Add(new Vector3(0, 0, 1));
// Initialize the ArrayMesh.
var arrMesh = new ArrayMesh();
var arrays = new Godot.Collections.Array();
arrays.Resize((int)ArrayMesh.ArrayType.Max);
arrays[(int)ArrayMesh.ArrayType.Vertex] = vertices;
// Create the Mesh.
arrMesh.AddSurfaceFromArrays(Mesh.PrimitiveType.Triangles, arrays);
var m = new MeshInstance();
m.Mesh = arrMesh;
[/csharp]
[/codeblocks]
The [MeshInstance3D] is ready to be added to the [SceneTree] to be shown.
See also [ImmediateGeometry3D], [MeshDataTool] and [SurfaceTool] for procedural geometry generation.
[b]Note:[/b] Godot uses clockwise [url=https://learnopengl.com/Advanced-OpenGL/Face-culling]winding order[/url] for front faces of triangle primitive modes.

View file

@ -6,7 +6,8 @@
<description>
Button is the standard themed button. It can contain text and an icon, and will display them according to the current [Theme].
[b]Example of creating a button and assigning an action when pressed by code:[/b]
[codeblock]
[codeblocks]
[gdscript]
func _ready():
var button = Button.new()
button.text = "Click me"
@ -15,7 +16,22 @@
func _button_pressed():
print("Hello world!")
[/codeblock]
[/gdscript]
[csharp]
public override void _Ready()
{
var button = new Button();
button.Text = "Click me";
button.Connect("pressed", this, nameof(ButtonPressed));
AddChild(button);
}
private void ButtonPressed()
{
GD.Print("Hello world!");
}
[/csharp]
[/codeblocks]
Buttons (like all Control nodes) can also be created in the editor, but some situations may require creating them from code.
See also [BaseButton] which contains common properties and methods associated with this node.
</description>

View file

@ -6,36 +6,87 @@
<description>
Boolean is a built-in type. There are two boolean values: [code]true[/code] and [code]false[/code]. You can think of it as an switch with on or off (1 or 0) setting. Booleans are used in programming for logic in condition statements, like [code]if[/code] statements.
Booleans can be directly used in [code]if[/code] statements. The code below demonstrates this on the [code]if can_shoot:[/code] line. You don't need to use [code]== true[/code], you only need [code]if can_shoot:[/code]. Similarly, use [code]if not can_shoot:[/code] rather than [code]== false[/code].
[codeblock]
var can_shoot = true
[codeblocks]
[gdscript]
var _can_shoot = true
func shoot():
if can_shoot:
if _can_shoot:
pass # Perform shooting actions here.
[/codeblock]
[/gdscript]
[csharp]
private bool _canShoot = true;
public void Shoot()
{
if (_canShoot)
{
// Perform shooting actions here.
}
}
[/csharp]
[/codeblocks]
The following code will only create a bullet if both conditions are met: action "shoot" is pressed and if [code]can_shoot[/code] is [code]true[/code].
[b]Note:[/b] [code]Input.is_action_pressed("shoot")[/code] is also a boolean that is [code]true[/code] when "shoot" is pressed and [code]false[/code] when "shoot" isn't pressed.
[codeblock]
var can_shoot = true
[codeblocks]
[gdscript]
var _can_shoot = true
func shoot():
if can_shoot and Input.is_action_pressed("shoot"):
if _can_shoot and Input.is_action_pressed("shoot"):
create_bullet()
[/codeblock]
[/gdscript]
[csharp]
private bool _canShoot = true;
public void Shoot()
{
if (_canShoot &amp;&amp; Input.IsActionPressed("shoot"))
{
CreateBullet();
}
}
[/csharp]
[/codeblocks]
The following code will set [code]can_shoot[/code] to [code]false[/code] and start a timer. This will prevent player from shooting until the timer runs out. Next [code]can_shoot[/code] will be set to [code]true[/code] again allowing player to shoot once again.
[codeblock]
var can_shoot = true
onready var cool_down = $CoolDownTimer
[gdscript]
var _can_shoot = true
onready var _cool_down = $CoolDownTimer
func shoot():
if can_shoot and Input.is_action_pressed("shoot"):
if _can_shoot and Input.is_action_pressed("shoot"):
create_bullet()
can_shoot = false
cool_down.start()
_can_shoot = false
_cool_down.start()
func _on_CoolDownTimer_timeout():
can_shoot = true
[/codeblock]
_can_shoot = true
[/gdscript]
[csharp]
private bool _canShoot = true;
private Timer _coolDown;
public override void _Ready()
{
_coolDown = GetNode&lt;Timer&gt;("CoolDownTimer");
}
public void Shoot()
{
if (_canShoot &amp;&amp; Input.IsActionPressed("shoot"))
{
CreateBullet();
_canShoot = false;
_coolDown.Start();
}
}
public void OnCoolDownTimerTimeout()
{
_canShoot = true;
}
[/csharp]
[/codeblocks]
</description>
<tutorials>
</tutorials>