summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/classes/@GlobalScope.xml8
-rw-r--r--doc/classes/AESContext.xml33
-rw-r--r--doc/classes/AStar3D.xml11
-rw-r--r--doc/classes/AnimationNodeStateMachine.xml5
-rw-r--r--doc/classes/AnimationNodeTransition.xml3
-rw-r--r--doc/classes/Color.xml13
-rw-r--r--doc/classes/Control.xml53
-rw-r--r--doc/classes/Crypto.xml30
-rw-r--r--doc/classes/DTLSServer.xml67
-rw-r--r--doc/classes/Dictionary.xml4
-rw-r--r--doc/classes/DirAccess.xml4
-rw-r--r--doc/classes/EditorImportPlugin.xml38
-rw-r--r--doc/classes/EditorPlugin.xml35
-rw-r--r--doc/classes/EditorScenePostImport.xml7
-rw-r--r--doc/classes/EditorScript.xml3
-rw-r--r--doc/classes/EditorSettings.xml2
-rw-r--r--doc/classes/EditorTranslationParserPlugin.xml24
-rw-r--r--doc/classes/Expression.xml10
-rw-r--r--doc/classes/FileAccess.xml4
-rw-r--r--doc/classes/Geometry2D.xml7
-rw-r--r--doc/classes/GraphEdit.xml5
-rw-r--r--doc/classes/HMACContext.xml19
-rw-r--r--doc/classes/HTTPClient.xml13
-rw-r--r--doc/classes/HTTPRequest.xml16
-rw-r--r--doc/classes/HashingContext.xml16
-rw-r--r--doc/classes/InputEventMIDI.xml20
-rw-r--r--doc/classes/MainLoop.xml15
-rw-r--r--doc/classes/NavigationAgent2D.xml15
-rw-r--r--doc/classes/NavigationAgent3D.xml12
-rw-r--r--doc/classes/NavigationServer2D.xml5
-rw-r--r--doc/classes/Object.xml20
-rw-r--r--doc/classes/ProjectSettings.xml16
-rw-r--r--doc/classes/RichTextEffect.xml2
-rw-r--r--doc/classes/SceneTree.xml4
-rw-r--r--doc/classes/SceneTreeTimer.xml4
-rw-r--r--doc/classes/Sprite2D.xml6
-rw-r--r--doc/classes/StreamPeer.xml2
-rw-r--r--doc/classes/SubViewport.xml1
-rw-r--r--doc/classes/SubViewportContainer.xml1
-rw-r--r--doc/classes/Tween.xml8
-rw-r--r--doc/classes/UDPServer.xml54
-rw-r--r--doc/classes/UndoRedo.xml16
-rw-r--r--modules/gdscript/doc_classes/@GDScript.xml12
-rw-r--r--modules/gdscript/gdscript_utility_functions.cpp23
-rw-r--r--modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs4
-rw-r--r--scene/2d/navigation_agent_2d.cpp162
-rw-r--r--scene/2d/navigation_agent_2d.h31
-rw-r--r--scene/3d/navigation_agent_3d.cpp180
-rw-r--r--scene/3d/navigation_agent_3d.h30
-rw-r--r--scene/animation/animation_blend_tree.cpp32
-rw-r--r--scene/animation/animation_blend_tree.h4
-rw-r--r--scene/animation/animation_node_state_machine.cpp15
-rw-r--r--scene/animation/animation_node_state_machine.h4
-rw-r--r--scene/gui/subviewport_container.cpp4
-rw-r--r--scene/main/viewport.cpp19
-rw-r--r--scene/main/viewport.h3
-rw-r--r--servers/navigation_server_2d.cpp36
-rw-r--r--servers/navigation_server_2d.h14
-rw-r--r--servers/navigation_server_3d.cpp98
-rw-r--r--servers/navigation_server_3d.h23
60 files changed, 998 insertions, 327 deletions
diff --git a/doc/classes/@GlobalScope.xml b/doc/classes/@GlobalScope.xml
index 0d6524ccbe..3b2e260dcb 100644
--- a/doc/classes/@GlobalScope.xml
+++ b/doc/classes/@GlobalScope.xml
@@ -1271,7 +1271,13 @@
<method name="str" qualifiers="vararg">
<return type="String" />
<description>
- Converts one or more arguments of any [Variant] type to [String] in the best way possible.
+ Converts one or more arguments of any [Variant] type to a [String] in the best way possible.
+ [codeblock]
+ var a = [10, 20, 30]
+ var b = str(a)
+ print(len(a)) # Prints 3 (the number of elements in the array).
+ print(len(b)) # Prints 12 (the length of the string "[10, 20, 30]").
+ [/codeblock]
</description>
</method>
<method name="str_to_var">
diff --git a/doc/classes/AESContext.xml b/doc/classes/AESContext.xml
index 7f582e4be7..747968ea91 100644
--- a/doc/classes/AESContext.xml
+++ b/doc/classes/AESContext.xml
@@ -39,39 +39,38 @@
[/gdscript]
[csharp]
using Godot;
- using System;
using System.Diagnostics;
- public class Example : Node
+ public partial class MyNode : Node
{
- public AESContext Aes = new AESContext();
+ private 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();
+ _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();
+ _aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8());
+ byte[] decrypted = _aes.Update(encrypted);
+ _aes.Finish();
// Check ECB
- Debug.Assert(decrypted == data.ToUTF8());
+ 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();
+ _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();
+ _aes.Start(AesContext.Mode.EcbDecrypt, key.ToUtf8(), iv.ToUtf8());
+ decrypted = _aes.Update(encrypted);
+ _aes.Finish();
// Check CBC
- Debug.Assert(decrypted == data.ToUTF8());
+ Debug.Assert(decrypted == data.ToUtf8());
}
}
[/csharp]
diff --git a/doc/classes/AStar3D.xml b/doc/classes/AStar3D.xml
index 4e8394195d..f0481c1745 100644
--- a/doc/classes/AStar3D.xml
+++ b/doc/classes/AStar3D.xml
@@ -19,15 +19,16 @@
return min(0, abs(u - v) - 1)
[/gdscript]
[csharp]
- public class MyAStar : AStar3D
+ public partial class MyAStar : AStar3D
{
- public override float _ComputeCost(int u, int v)
+ public override float _ComputeCost(long fromId, long toId)
{
- return Mathf.Abs(u - v);
+ return Mathf.Abs((int)(fromId - toId));
}
- public override float _EstimateCost(int u, int v)
+
+ public override float _EstimateCost(long fromId, long toId)
{
- return Mathf.Min(0, Mathf.Abs(u - v) - 1);
+ return Mathf.Min(0, Mathf.Abs((int)(fromId - toId)) - 1);
}
}
[/csharp]
diff --git a/doc/classes/AnimationNodeStateMachine.xml b/doc/classes/AnimationNodeStateMachine.xml
index 0fb789875f..95891a9061 100644
--- a/doc/classes/AnimationNodeStateMachine.xml
+++ b/doc/classes/AnimationNodeStateMachine.xml
@@ -161,4 +161,9 @@
</description>
</method>
</methods>
+ <members>
+ <member name="allow_transition_to_self" type="bool" setter="set_allow_transition_to_self" getter="is_allow_transition_to_self" default="false">
+ If [code]true[/code], allows teleport to the self state with [method AnimationNodeStateMachinePlayback.travel]. When the reset option is enabled in [method AnimationNodeStateMachinePlayback.travel], the animation is restarted. If [code]false[/code], nothing happens on the teleportation to the self state.
+ </member>
+ </members>
</class>
diff --git a/doc/classes/AnimationNodeTransition.xml b/doc/classes/AnimationNodeTransition.xml
index a067b0a9ba..bc3e5716dd 100644
--- a/doc/classes/AnimationNodeTransition.xml
+++ b/doc/classes/AnimationNodeTransition.xml
@@ -44,6 +44,9 @@
</method>
</methods>
<members>
+ <member name="allow_transition_to_self" type="bool" setter="set_allow_transition_to_self" getter="is_allow_transition_to_self" default="false">
+ If [code]true[/code], allows transition to the self state. When the reset option is enabled in input, the animation is restarted. If [code]false[/code], nothing happens on the transition to the self state.
+ </member>
<member name="input_count" type="int" setter="set_input_count" getter="get_input_count" default="0">
The number of enabled input ports for this node.
</member>
diff --git a/doc/classes/Color.xml b/doc/classes/Color.xml
index 57278d9241..cee0e3ef7d 100644
--- a/doc/classes/Color.xml
+++ b/doc/classes/Color.xml
@@ -233,7 +233,6 @@
<description>
Returns a new color from [param rgba], an HTML hexadecimal color string. [param rgba] is not case-sensitive, and may be prefixed by a hash sign ([code]#[/code]).
[param rgba] must be a valid three-digit or six-digit hexadecimal color string, and may contain an alpha channel value. If [param rgba] does not contain an alpha channel value, an alpha channel value of 1.0 is applied. If [param rgba] is invalid, returns an empty color.
- [b]Note:[/b] In C#, this method is not implemented. The same functionality is provided by the Color constructor.
[codeblocks]
[gdscript]
var blue = Color.html("#0000ff") # blue is Color(0.0, 0.0, 1.0, 1.0)
@@ -264,13 +263,13 @@
Color.html_is_valid("#55aaFF5") # Returns false
[/gdscript]
[csharp]
- Color.IsHtmlValid("#55AAFF"); // Returns true
- Color.IsHtmlValid("#55AAFF20"); // Returns true
- Color.IsHtmlValid("55AAFF"); // Returns true
- Color.IsHtmlValid("#F2C"); // Returns true
+ Color.HtmlIsValid("#55AAFF"); // Returns true
+ Color.HtmlIsValid("#55AAFF20"); // Returns true
+ Color.HtmlIsValid("55AAFF"); // Returns true
+ Color.HtmlIsValid("#F2C"); // Returns true
- Color.IsHtmlValid("#AABBC"); // Returns false
- Color.IsHtmlValid("#55aaFF5"); // Returns false
+ Color.HtmlIsValid("#AABBC"); // Returns false
+ Color.HtmlIsValid("#55aaFF5"); // Returns false
[/csharp]
[/codeblocks]
</description>
diff --git a/doc/classes/Control.xml b/doc/classes/Control.xml
index 0d675112b8..d74ddba369 100644
--- a/doc/classes/Control.xml
+++ b/doc/classes/Control.xml
@@ -37,11 +37,11 @@
return typeof(data) == TYPE_DICTIONARY and data.has("expected")
[/gdscript]
[csharp]
- public override bool CanDropData(Vector2 position, object data)
+ public override bool _CanDropData(Vector2 atPosition, Variant data)
{
// Check position if it is relevant to you
// Otherwise, just check data
- return data is Godot.Collections.Dictionary &amp;&amp; (data as Godot.Collections.Dictionary).Contains("expected");
+ return data.VariantType == Variant.Type.Dictionary &amp;&amp; data.AsGodotDictionary().Contains("expected");
}
[/csharp]
[/codeblocks]
@@ -57,17 +57,19 @@
[gdscript]
func _can_drop_data(position, data):
return typeof(data) == TYPE_DICTIONARY and data.has("color")
+
func _drop_data(position, data):
var color = data["color"]
[/gdscript]
[csharp]
- public override bool CanDropData(Vector2 position, object data)
+ public override bool _CanDropData(Vector2 atPosition, Variant data)
{
- return data is Godot.Collections.Dictionary &amp;&amp; (data as Godot.Collections.Dictionary).Contains("color");
+ return data.VariantType == Variant.Type.Dictionary &amp;&amp; dict.AsGodotDictionary().Contains("color");
}
- public override void DropData(Vector2 position, object data)
+
+ public override void _DropData(Vector2 atPosition, Variant data)
{
- Color color = (Color)(data as Godot.Collections.Dictionary)["color"];
+ Color color = data.AsGodotDictionary()["color"].AsColor();
}
[/csharp]
[/codeblocks]
@@ -87,11 +89,11 @@
return mydata
[/gdscript]
[csharp]
- public override object GetDragData(Vector2 position)
+ public override Variant _GetDragData(Vector2 atPosition)
{
- object mydata = MakeData(); // This is your custom method generating the drag data.
- SetDragPreview(MakePreview(mydata)); // This is your custom method generating the preview of the drag data.
- return mydata;
+ var myData = MakeData(); // This is your custom method generating the drag data.
+ SetDragPreview(MakePreview(myData)); // This is your custom method generating the preview of the drag data.
+ return myData;
}
[/csharp]
[/codeblocks]
@@ -121,10 +123,9 @@
[csharp]
public override void _GuiInput(InputEvent @event)
{
- if (@event is InputEventMouseButton)
+ if (@event is InputEventMouseButton mb)
{
- var mb = @event as InputEventMouseButton;
- if (mb.ButtonIndex == (int)ButtonList.Left &amp;&amp; mb.Pressed)
+ if (mb.ButtonIndex == MouseButton.Left &amp;&amp; mb.Pressed)
{
GD.Print("I've been clicked D:");
}
@@ -168,7 +169,7 @@
return label
[/gdscript]
[csharp]
- public override Godot.Control _MakeCustomTooltip(String forText)
+ public override Control _MakeCustomTooltip(string forText)
{
var label = new Label();
label.Text = forText;
@@ -185,7 +186,7 @@
return tooltip
[/gdscript]
[csharp]
- public override Godot.Control _MakeCustomTooltip(String forText)
+ public override Control _MakeCustomTooltip(string forText)
{
Node tooltip = ResourceLoader.Load&lt;PackedScene&gt;("res://some_tooltip_scene.tscn").Instantiate();
tooltip.GetNode&lt;Label&gt;("Label").Text = forText;
@@ -229,11 +230,11 @@
[/gdscript]
[csharp]
// Given the child Label node "MyLabel", override its font color with a custom value.
- GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", new Color(1, 0.5f, 0))
+ GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", new Color(1, 0.5f, 0));
// Reset the font color of the child label.
- GetNode&lt;Label&gt;("MyLabel").RemoveThemeColorOverride("font_color")
+ GetNode&lt;Label&gt;("MyLabel").RemoveThemeColorOverride("font_color");
// Alternatively it can be overridden with the default value from the Label type.
- GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", GetThemeColor("font_color", "Label"))
+ GetNode&lt;Label&gt;("MyLabel").AddThemeColorOverride("font_color", GetThemeColor("font_color", "Label"));
[/csharp]
[/codeblocks]
</description>
@@ -542,12 +543,12 @@
[codeblocks]
[gdscript]
func _process(delta):
- grab_click_focus() #when clicking another Control node, this node will be clicked instead
+ grab_click_focus() # When clicking another Control node, this node will be clicked instead.
[/gdscript]
[csharp]
- public override void _Process(float delta)
+ public override void _Process(double delta)
{
- GrabClickFocus(); //when clicking another Control node, this node will be clicked instead
+ GrabClickFocus(); // When clicking another Control node, this node will be clicked instead.
}
[/csharp]
[/codeblocks]
@@ -812,16 +813,16 @@
[/gdscript]
[csharp]
[Export]
- public Color Color = new Color(1, 0, 0, 1);
+ private Color _color = new Color(1, 0, 0, 1);
- public override object GetDragData(Vector2 position)
+ public override Variant _GetDragData(Vector2 atPosition)
{
// Use a control that is not in the tree
var cpb = new ColorPickerButton();
- cpb.Color = Color;
- cpb.RectSize = new Vector2(50, 50);
+ cpb.Color = _color;
+ cpb.Size = new Vector2(50, 50);
SetDragPreview(cpb);
- return Color;
+ return _color;
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/Crypto.xml b/doc/classes/Crypto.xml
index ade63225dc..a7e7e756c6 100644
--- a/doc/classes/Crypto.xml
+++ b/doc/classes/Crypto.xml
@@ -9,9 +9,11 @@
[codeblocks]
[gdscript]
extends Node
+
var crypto = Crypto.new()
var key = CryptoKey.new()
var cert = X509Certificate.new()
+
func _ready():
# Generate new RSA key.
key = crypto.generate_rsa(4096)
@@ -35,35 +37,35 @@
[/gdscript]
[csharp]
using Godot;
- using System;
using System.Diagnostics;
- public class CryptoNode : Node
+ public partial class MyNode : Node
{
- public Crypto Crypto = new Crypto();
- public CryptoKey Key = new CryptoKey();
- public X509Certificate Cert = new X509Certificate();
+ private Crypto _crypto = new Crypto();
+ private CryptoKey _key = new CryptoKey();
+ private X509Certificate _cert = new X509Certificate();
+
public override void _Ready()
{
// Generate new RSA key.
- Key = Crypto.GenerateRsa(4096);
+ _key = _crypto.GenerateRsa(4096);
// Generate new self-signed certificate with the given key.
- Cert = Crypto.GenerateSelfSignedCertificate(Key, "CN=mydomain.com,O=My Game Company,C=IT");
+ _cert = _crypto.GenerateSelfSignedCertificate(_key, "CN=mydomain.com,O=My Game Company,C=IT");
// Save key and certificate in the user folder.
- Key.Save("user://generated.key");
- Cert.Save("user://generated.crt");
+ _key.Save("user://generated.key");
+ _cert.Save("user://generated.crt");
// Encryption
string data = "Some data";
- byte[] encrypted = Crypto.Encrypt(Key, data.ToUTF8());
+ byte[] encrypted = _crypto.Encrypt(_key, data.ToUtf8());
// Decryption
- byte[] decrypted = Crypto.Decrypt(Key, encrypted);
+ byte[] decrypted = _crypto.Decrypt(_key, encrypted);
// Signing
- byte[] signature = Crypto.Sign(HashingContext.HashType.Sha256, Data.SHA256Buffer(), Key);
+ byte[] signature = _crypto.Sign(HashingContext.HashType.Sha256, Data.Sha256Buffer(), _key);
// Verifying
- bool verified = Crypto.Verify(HashingContext.HashType.Sha256, Data.SHA256Buffer(), signature, Key);
+ bool verified = _crypto.Verify(HashingContext.HashType.Sha256, Data.Sha256Buffer(), signature, _key);
// Checks
Debug.Assert(verified);
- Debug.Assert(data.ToUTF8() == decrypted);
+ Debug.Assert(data.ToUtf8() == decrypted);
}
}
[/csharp]
diff --git a/doc/classes/DTLSServer.xml b/doc/classes/DTLSServer.xml
index a3a0b0456c..ae1ba10ec7 100644
--- a/doc/classes/DTLSServer.xml
+++ b/doc/classes/DTLSServer.xml
@@ -38,45 +38,46 @@
p.put_packet("Hello DTLS client".to_utf8())
[/gdscript]
[csharp]
- using Godot;
- using System;
// ServerNode.cs
- public class ServerNode : Node
+ using Godot;
+
+ public partial class ServerNode : Node
{
- public DTLSServer Dtls = new DTLSServer();
- public UDPServer Server = new UDPServer();
- public Godot.Collections.Array&lt;PacketPeerDTLS&gt; Peers = new Godot.Collections.Array&lt;PacketPeerDTLS&gt;();
+ private DtlsServer _dtls = new DtlsServer();
+ private UdpServer _server = new UdpServer();
+ private Godot.Collections.Array&lt;PacketPeerDTLS&gt; _peers = new Godot.Collections.Array&lt;PacketPeerDTLS&gt;();
+
public override void _Ready()
{
- Server.Listen(4242);
+ _server.Listen(4242);
var key = GD.Load&lt;CryptoKey&gt;("key.key"); // Your private key.
var cert = GD.Load&lt;X509Certificate&gt;("cert.crt"); // Your X509 certificate.
- Dtls.Setup(key, cert);
+ _dtls.Setup(key, cert);
}
- public override void _Process(float delta)
+ public override void _Process(double delta)
{
while (Server.IsConnectionAvailable())
{
- PacketPeerUDP peer = Server.TakeConnection();
- PacketPeerDTLS dtlsPeer = Dtls.TakeConnection(peer);
- if (dtlsPeer.GetStatus() != PacketPeerDTLS.Status.Handshaking)
+ PacketPeerUDP peer = _server.TakeConnection();
+ PacketPeerDTLS dtlsPeer = _dtls.TakeConnection(peer);
+ if (dtlsPeer.GetStatus() != PacketPeerDtls.Status.Handshaking)
{
continue; // It is normal that 50% of the connections fails due to cookie exchange.
}
GD.Print("Peer connected!");
- Peers.Add(dtlsPeer);
+ _peers.Add(dtlsPeer);
}
- foreach (var p in Peers)
+ foreach (var p in _peers)
{
p.Poll(); // Must poll to update the state.
- if (p.GetStatus() == PacketPeerDTLS.Status.Connected)
+ if (p.GetStatus() == PacketPeerDtls.Status.Connected)
{
while (p.GetAvailablePacketCount() &gt; 0)
{
- GD.Print("Received Message From Client: " + p.GetPacket().GetStringFromUTF8());
- p.PutPacket("Hello Dtls Client".ToUTF8());
+ GD.Print($"Received Message From Client: {p.GetPacket().GetStringFromUtf8()}");
+ p.PutPacket("Hello DTLS Client".ToUtf8());
}
}
}
@@ -108,34 +109,36 @@
connected = true
[/gdscript]
[csharp]
+ // ClientNode.cs
using Godot;
using System.Text;
- // ClientNode.cs
- public class ClientNode : Node
+
+ public partial class ClientNode : Node
{
- public PacketPeerDTLS Dtls = new PacketPeerDTLS();
- public PacketPeerUDP Udp = new PacketPeerUDP();
- public bool Connected = false;
+ private PacketPeerDtls _dtls = new PacketPeerDtls();
+ private PacketPeerUdp _udp = new PacketPeerUdp();
+ private bool _connected = false;
+
public override void _Ready()
{
- Udp.ConnectToHost("127.0.0.1", 4242);
- Dtls.ConnectToPeer(Udp, false); // Use true in production for certificate validation!
+ _udp.ConnectToHost("127.0.0.1", 4242);
+ _dtls.ConnectToPeer(_udp, validateCerts: false); // Use true in production for certificate validation!
}
- public override void _Process(float delta)
+ public override void _Process(double delta)
{
- Dtls.Poll();
- if (Dtls.GetStatus() == PacketPeerDTLS.Status.Connected)
+ _dtls.Poll();
+ if (_dtls.GetStatus() == PacketPeerDtls.Status.Connected)
{
- if (!Connected)
+ if (!_connected)
{
// Try to contact server
- Dtls.PutPacket("The Answer Is..42!".ToUTF8());
+ _dtls.PutPacket("The Answer Is..42!".ToUtf8());
}
- while (Dtls.GetAvailablePacketCount() &gt; 0)
+ while (_dtls.GetAvailablePacketCount() &gt; 0)
{
- GD.Print("Connected: " + Dtls.GetPacket().GetStringFromUTF8());
- Connected = true;
+ GD.Print($"Connected: {_dtls.GetPacket().GetStringFromUtf8()}");
+ _connected = true;
}
}
}
diff --git a/doc/classes/Dictionary.xml b/doc/classes/Dictionary.xml
index 1591aa59bf..a5a50b4c6a 100644
--- a/doc/classes/Dictionary.xml
+++ b/doc/classes/Dictionary.xml
@@ -51,7 +51,7 @@
[csharp]
[Export(PropertyHint.Enum, "White,Yellow,Orange")]
public string MyColor { get; set; }
- public Godot.Collections.Dictionary pointsDict = new Godot.Collections.Dictionary
+ private Godot.Collections.Dictionary _pointsDict = new Godot.Collections.Dictionary
{
{"White", 50},
{"Yellow", 75},
@@ -60,7 +60,7 @@
public override void _Ready()
{
- int points = (int)pointsDict[MyColor];
+ int points = (int)_pointsDict[MyColor];
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/DirAccess.xml b/doc/classes/DirAccess.xml
index 181d2eb485..27f2eb7f2f 100644
--- a/doc/classes/DirAccess.xml
+++ b/doc/classes/DirAccess.xml
@@ -44,11 +44,11 @@
{
if (dir.CurrentIsDir())
{
- GD.Print("Found directory: " + fileName);
+ GD.Print($"Found directory: {fileName}");
}
else
{
- GD.Print("Found file: " + fileName);
+ GD.Print($"Found file: {fileName}");
}
fileName = dir.GetNext();
}
diff --git a/doc/classes/EditorImportPlugin.xml b/doc/classes/EditorImportPlugin.xml
index ec9efcc9c4..b30ce5a528 100644
--- a/doc/classes/EditorImportPlugin.xml
+++ b/doc/classes/EditorImportPlugin.xml
@@ -48,61 +48,67 @@
[/gdscript]
[csharp]
using Godot;
- using System;
- public class MySpecialPlugin : EditorImportPlugin
+ public partial class MySpecialPlugin : EditorImportPlugin
{
- public override String GetImporterName()
+ public override string _GetImporterName()
{
return "my.special.plugin";
}
- public override String GetVisibleName()
+ public override string _GetVisibleName()
{
return "Special Mesh";
}
- public override Godot.Collections.Array GetRecognizedExtensions()
+ public override string[] _GetRecognizedExtensions()
{
- return new Godot.Collections.Array{"special", "spec"};
+ return new string[] { "special", "spec" };
}
- public override String GetSaveExtension()
+ public override string _GetSaveExtension()
{
return "mesh";
}
- public override String GetResourceType()
+ public override string _GetResourceType()
{
return "Mesh";
}
- public override int GetPresetCount()
+ public override int _GetPresetCount()
{
return 1;
}
- public override String GetPresetName(int i)
+ public override string _GetPresetName(int presetIndex)
{
return "Default";
}
- public override Godot.Collections.Array GetImportOptions(int i)
+ public override Godot.Collections.Array&lt;Godot.Collections.Dictionary&gt; _GetImportOptions(string path, int presetIndex)
{
- return new Godot.Collections.Array{new Godot.Collections.Dictionary{{"name", "myOption"}, {"defaultValue", false}}};
+ return new Godot.Collections.Array&lt;Godot.Collections.Dictionary&gt;
+ {
+ new Godot.Collections.Dictionary
+ {
+ { "name", "myOption" },
+ { "defaultValue", false },
+ }
+ };
}
- public override int Import(String sourceFile, String savePath, Godot.Collections.Dictionary options, Godot.Collections.Array platformVariants, Godot.Collections.Array genFiles)
+ public override int _Import(string sourceFile, string savePath, Godot.Collections.Dictionary options, Godot.Collections.Array&lt;string&gt; platformVariants, Godot.Collections.Array&lt;string&gt; genFiles)
{
- var file = new File();
- if (file.Open(sourceFile, File.ModeFlags.Read) != Error.Ok)
+ using var file = FileAccess.Open(sourceFile, FileAccess.ModeFlags.Read);
+ if (file.GetError() != Error.Ok)
{
return (int)Error.Failed;
}
var mesh = new ArrayMesh();
// Fill the Mesh with data read in "file", left as an exercise to the reader.
- String filename = savePath + "." + GetSaveExtension();
+ string filename = $"{savePath}.{_GetSaveExtension()}";
return (int)ResourceSaver.Save(mesh, filename);
}
}
diff --git a/doc/classes/EditorPlugin.xml b/doc/classes/EditorPlugin.xml
index c097c8f685..f4b912de9e 100644
--- a/doc/classes/EditorPlugin.xml
+++ b/doc/classes/EditorPlugin.xml
@@ -69,21 +69,22 @@
return EditorPlugin.AFTER_GUI_INPUT_PASS
[/gdscript]
[csharp]
- public override void _Forward3dDrawOverViewport(Godot.Control overlay)
+ public override void _Forward3DDrawOverViewport(Control viewportControl)
{
// Draw a circle at cursor position.
- overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White);
+ viewportControl.DrawCircle(viewportControl.GetLocalMousePosition(), 64, Colors.White);
}
- public override EditorPlugin.AfterGUIInput _Forward3dGuiInput(Godot.Camera3D camera, InputEvent @event)
+ public override EditorPlugin.AfterGuiInput _Forward3DGuiInput(Camera3D viewportCamera, InputEvent @event)
{
if (@event is InputEventMouseMotion)
{
// Redraw viewport when cursor is moved.
UpdateOverlays();
- return EditorPlugin.AFTER_GUI_INPUT_STOP;
+ return EditorPlugin.AfterGuiInput.Stop;
}
- return EditorPlugin.AFTER_GUI_INPUT_PASS;
+ return EditorPlugin.AfterGuiInput.Pass;
+ }
[/csharp]
[/codeblocks]
</description>
@@ -111,9 +112,9 @@
[/gdscript]
[csharp]
// Prevents the InputEvent from reaching other Editor classes.
- public override EditorPlugin.AfterGUIInput _Forward3dGuiInput(Camera3D camera, InputEvent @event)
+ public override EditorPlugin.AfterGuiInput _Forward3DGuiInput(Camera3D camera, InputEvent @event)
{
- return EditorPlugin.AFTER_GUI_INPUT_STOP;
+ return EditorPlugin.AfterGuiInput.Stop;
}
[/csharp]
[/codeblocks]
@@ -127,9 +128,9 @@
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
- public override EditorPlugin.AfterGUIInput _Forward3dGuiInput(Camera3D camera, InputEvent @event)
+ public override EditorPlugin.AfterGuiInput _Forward3DGuiInput(Camera3D camera, InputEvent @event)
{
- return @event is InputEventMouseMotion ? EditorPlugin.AFTER_GUI_INPUT_STOP : EditorPlugin.AFTER_GUI_INPUT_PASS;
+ return @event is InputEventMouseMotion ? EditorPlugin.AfterGuiInput.Stop : EditorPlugin.AfterGuiInput.Pass;
}
[/csharp]
[/codeblocks]
@@ -154,13 +155,13 @@
return false
[/gdscript]
[csharp]
- public override void ForwardCanvasDrawOverViewport(Godot.Control overlay)
+ public override void _ForwardCanvasDrawOverViewport(Control viewportControl)
{
// Draw a circle at cursor position.
- overlay.DrawCircle(overlay.GetLocalMousePosition(), 64, Colors.White);
+ viewportControl.DrawCircle(viewportControl.GetLocalMousePosition(), 64, Colors.White);
}
- public override bool ForwardCanvasGuiInput(InputEvent @event)
+ public override bool _ForwardCanvasGuiInput(InputEvent @event)
{
if (@event is InputEventMouseMotion)
{
@@ -169,6 +170,7 @@
return true;
}
return false;
+ }
[/csharp]
[/codeblocks]
</description>
@@ -213,12 +215,13 @@
[/gdscript]
[csharp]
// Consumes InputEventMouseMotion and forwards other InputEvent types.
- public override bool ForwardCanvasGuiInput(InputEvent @event)
+ public override bool _ForwardCanvasGuiInput(InputEvent @event)
{
- if (@event is InputEventMouseMotion) {
+ if (@event is InputEventMouseMotion)
+ {
return true;
}
- return false
+ return false;
}
[/csharp]
[/codeblocks]
@@ -245,7 +248,7 @@
return get_editor_interface().get_base_control().get_theme_icon("Node", "EditorIcons")
[/gdscript]
[csharp]
- public override Texture2D GetPluginIcon()
+ public override Texture2D _GetPluginIcon()
{
// You can use a custom icon:
return ResourceLoader.Load&lt;Texture2D&gt;("res://addons/my_plugin/my_plugin_icon.svg");
diff --git a/doc/classes/EditorScenePostImport.xml b/doc/classes/EditorScenePostImport.xml
index d2ad8d1bed..44bc72ea49 100644
--- a/doc/classes/EditorScenePostImport.xml
+++ b/doc/classes/EditorScenePostImport.xml
@@ -10,12 +10,14 @@
[gdscript]
@tool # Needed so it runs in editor.
extends EditorScenePostImport
+
# This sample changes all node names.
# Called right after the scene is imported and gets the root node.
func _post_import(scene):
# Change all node names to "modified_[oldnodename]"
iterate(scene)
return scene # Remember to return the imported scene
+
func iterate(node):
if node != null:
node.name = "modified_" + node.name
@@ -30,17 +32,18 @@
[Tool]
public partial class NodeRenamer : EditorScenePostImport
{
- public override Object _PostImport(Node scene)
+ public override GodotObject _PostImport(Node scene)
{
// Change all node names to "modified_[oldnodename]"
Iterate(scene);
return scene; // Remember to return the imported scene
}
+
public void Iterate(Node node)
{
if (node != null)
{
- node.Name = "modified_" + node.Name;
+ node.Name = $"modified_{node.Name}";
foreach (Node child in node.GetChildren())
{
Iterate(child);
diff --git a/doc/classes/EditorScript.xml b/doc/classes/EditorScript.xml
index a02fd215d8..33d2f40d0b 100644
--- a/doc/classes/EditorScript.xml
+++ b/doc/classes/EditorScript.xml
@@ -17,10 +17,9 @@
[/gdscript]
[csharp]
using Godot;
- using System;
[Tool]
- public class HelloEditor : EditorScript
+ public partial class HelloEditor : EditorScript
{
public override void _Run()
{
diff --git a/doc/classes/EditorSettings.xml b/doc/classes/EditorSettings.xml
index 72843eb157..1bf8cbf175 100644
--- a/doc/classes/EditorSettings.xml
+++ b/doc/classes/EditorSettings.xml
@@ -22,7 +22,7 @@
settings.SetSetting("some/property", Value);
// `settings.get("some/property", value)` also works as this class overrides `_get()` internally.
settings.GetSetting("some/property");
- Godot.Collections.Array listOfSettings = settings.GetPropertyList();
+ Godot.Collections.Array&lt;Godot.Collections.Dictionary&gt; listOfSettings = settings.GetPropertyList();
[/csharp]
[/codeblocks]
[b]Note:[/b] This class shouldn't be instantiated directly. Instead, access the singleton using [method EditorInterface.get_editor_settings].
diff --git a/doc/classes/EditorTranslationParserPlugin.xml b/doc/classes/EditorTranslationParserPlugin.xml
index 89746363d8..40b469de0a 100644
--- a/doc/classes/EditorTranslationParserPlugin.xml
+++ b/doc/classes/EditorTranslationParserPlugin.xml
@@ -27,27 +27,25 @@
[/gdscript]
[csharp]
using Godot;
- using System;
[Tool]
- public class CustomParser : EditorTranslationParserPlugin
+ public partial class CustomParser : EditorTranslationParserPlugin
{
- public override void ParseFile(string path, Godot.Collections.Array msgids, Godot.Collections.Array msgidsContextPlural)
+ public override void _ParseFile(string path, Godot.Collections.Array&lt;string&gt; msgids, Godot.Collections.Array&lt;Godot.Collections.Array&gt; msgidsContextPlural)
{
- var file = new File();
- file.Open(path, File.ModeFlags.Read);
+ using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
string text = file.GetAsText();
- string[] splitStrs = text.Split(",", false);
- foreach (var s in splitStrs)
+ string[] splitStrs = text.Split(",", allowEmpty: false);
+ foreach (string s in splitStrs)
{
msgids.Add(s);
- //GD.Print("Extracted string: " + s)
+ //GD.Print($"Extracted string: {s}");
}
}
- public override Godot.Collections.Array GetRecognizedExtensions()
+ public override string[] _GetRecognizedExtensions()
{
- return new Godot.Collections.Array{"csv"};
+ return new string[] { "csv" };
}
}
[/csharp]
@@ -84,16 +82,16 @@
return ["gd"]
[/gdscript]
[csharp]
- public override void ParseFile(string path, Godot.Collections.Array msgids, Godot.Collections.Array msgidsContextPlural)
+ public override void _ParseFile(string path, Godot.Collections.Array&lt;string&gt; msgids, Godot.Collections.Array&lt;Godot.Collections.Array&gt; msgidsContextPlural)
{
var res = ResourceLoader.Load&lt;Script&gt;(path, "Script");
string text = res.SourceCode;
// Parsing logic.
}
- public override Godot.Collections.Array GetRecognizedExtensions()
+ public override string[] _GetRecognizedExtensions()
{
- return new Godot.Collections.Array{"gd"};
+ return new string[] { "gd" };
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/Expression.xml b/doc/classes/Expression.xml
index 2c7d83a811..fd5a921836 100644
--- a/doc/classes/Expression.xml
+++ b/doc/classes/Expression.xml
@@ -24,7 +24,7 @@
$LineEdit.text = str(result)
[/gdscript]
[csharp]
- public Expression expression = new Expression();
+ private Expression _expression = new Expression();
public override void _Ready()
{
@@ -33,14 +33,14 @@
private void OnTextEntered(string command)
{
- Error error = expression.Parse(command);
+ Error error = _expression.Parse(command);
if (error != Error.Ok)
{
- GD.Print(expression.GetErrorText());
+ GD.Print(_expression.GetErrorText());
return;
}
- object result = expression.Execute();
- if (!expression.HasExecuteFailed())
+ Variant result = _expression.Execute();
+ if (!_expression.HasExecuteFailed())
{
GetNode&lt;LineEdit&gt;("LineEdit").Text = result.ToString();
}
diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml
index be0c8fd6ca..687a64b8ff 100644
--- a/doc/classes/FileAccess.xml
+++ b/doc/classes/FileAccess.xml
@@ -348,8 +348,8 @@
f.Seek(0); // Go back to start to read the stored value.
ushort read1 = f.Get16(); // 65494
ushort read2 = f.Get16(); // 121
- short converted1 = BitConverter.ToInt16(BitConverter.GetBytes(read1), 0); // -42
- short converted2 = BitConverter.ToInt16(BitConverter.GetBytes(read2), 0); // 121
+ short converted1 = (short)read1; // -42
+ short converted2 = (short)read2; // 121
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/Geometry2D.xml b/doc/classes/Geometry2D.xml
index 0142018f1a..f015026bc1 100644
--- a/doc/classes/Geometry2D.xml
+++ b/doc/classes/Geometry2D.xml
@@ -160,14 +160,13 @@
var polygon = PackedVector2Array([Vector2(0, 0), Vector2(100, 0), Vector2(100, 100), Vector2(0, 100)])
var offset = Vector2(50, 50)
polygon = Transform2D(0, offset) * polygon
- print(polygon) # prints [Vector2(50, 50), Vector2(150, 50), Vector2(150, 150), Vector2(50, 150)]
+ print(polygon) # prints [(50, 50), (150, 50), (150, 150), (50, 150)]
[/gdscript]
[csharp]
var polygon = new Vector2[] { new Vector2(0, 0), new Vector2(100, 0), new Vector2(100, 100), new Vector2(0, 100) };
var offset = new Vector2(50, 50);
- // TODO: This code is not valid right now. Ping @aaronfranke about it before Godot 4.0 is out.
- //polygon = (Vector2[]) new Transform2D(0, offset).Xform(polygon);
- //GD.Print(polygon); // prints [Vector2(50, 50), Vector2(150, 50), Vector2(150, 150), Vector2(50, 150)]
+ polygon = new Transform2D(0, offset) * polygon;
+ GD.Print((Variant)polygon); // prints [(50, 50), (150, 50), (150, 150), (50, 150)]
[/csharp]
[/codeblocks]
</description>
diff --git a/doc/classes/GraphEdit.xml b/doc/classes/GraphEdit.xml
index ea4e4b53ba..490637374d 100644
--- a/doc/classes/GraphEdit.xml
+++ b/doc/classes/GraphEdit.xml
@@ -72,8 +72,9 @@
return from != to
[/gdscript]
[csharp]
- public override bool _IsNodeHoverValid(String from, int fromSlot, String to, int toSlot) {
- return from != to;
+ public override bool _IsNodeHoverValid(StringName fromNode, int fromPort, StringName toNode, int toPort)
+ {
+ return fromNode != toNode;
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/HMACContext.xml b/doc/classes/HMACContext.xml
index 706ee30963..fbdc6b5e64 100644
--- a/doc/classes/HMACContext.xml
+++ b/doc/classes/HMACContext.xml
@@ -26,25 +26,24 @@
[/gdscript]
[csharp]
using Godot;
- using System;
using System.Diagnostics;
- public class CryptoNode : Node
+ public partial class MyNode : Node
{
- private HMACContext ctx = new HMACContext();
+ private HmacContext _ctx = new HmacContext();
public override void _Ready()
{
- byte[] key = "supersecret".ToUTF8();
- Error err = ctx.Start(HashingContext.HashType.Sha256, key);
+ byte[] key = "supersecret".ToUtf8();
+ Error err = _ctx.Start(HashingContext.HashType.Sha256, key);
Debug.Assert(err == Error.Ok);
- byte[] msg1 = "this is ".ToUTF8();
- byte[] msg2 = "super duper secret".ToUTF8();
- err = ctx.Update(msg1);
+ byte[] msg1 = "this is ".ToUtf8();
+ byte[] msg2 = "super duper secret".ToUtf8();
+ err = _ctx.Update(msg1);
Debug.Assert(err == Error.Ok);
- err = ctx.Update(msg2);
+ err = _ctx.Update(msg2);
Debug.Assert(err == Error.Ok);
- byte[] hmac = ctx.Finish();
+ byte[] hmac = _ctx.Finish();
GD.Print(hmac.HexEncode());
}
}
diff --git a/doc/classes/HTTPClient.xml b/doc/classes/HTTPClient.xml
index b7a5cff694..4973f3fddf 100644
--- a/doc/classes/HTTPClient.xml
+++ b/doc/classes/HTTPClient.xml
@@ -105,7 +105,7 @@
[/gdscript]
[csharp]
var fields = new Godot.Collections.Dictionary { { "username", "user" }, { "password", "pass" } };
- string queryString = new HTTPClient().QueryStringFromDict(fields);
+ string queryString = httpClient.QueryStringFromDict(fields);
// Returns "username=user&amp;password=pass"
[/csharp]
[/codeblocks]
@@ -117,8 +117,13 @@
# Returns "single=123&amp;not_valued&amp;multiple=22&amp;multiple=33&amp;multiple=44"
[/gdscript]
[csharp]
- var fields = new Godot.Collections.Dictionary{{"single", 123}, {"notValued", null}, {"multiple", new Godot.Collections.Array{22, 33, 44}}};
- string queryString = new HTTPClient().QueryStringFromDict(fields);
+ var fields = new Godot.Collections.Dictionary
+ {
+ { "single", 123 },
+ { "notValued", default },
+ { "multiple", new Godot.Collections.Array { 22, 33, 44 } },
+ };
+ string queryString = httpClient.QueryStringFromDict(fields);
// Returns "single=123&amp;not_valued&amp;multiple=22&amp;multiple=33&amp;multiple=44"
[/csharp]
[/codeblocks]
@@ -151,7 +156,7 @@
[csharp]
var fields = new Godot.Collections.Dictionary { { "username", "user" }, { "password", "pass" } };
string queryString = new HTTPClient().QueryStringFromDict(fields);
- string[] headers = {"Content-Type: application/x-www-form-urlencoded", "Content-Length: " + queryString.Length};
+ string[] headers = { "Content-Type: application/x-www-form-urlencoded", $"Content-Length: {queryString.Length}" };
var result = new HTTPClient().Request(HTTPClient.Method.Post, "index.php", headers, queryString);
[/csharp]
[/codeblocks]
diff --git a/doc/classes/HTTPRequest.xml b/doc/classes/HTTPRequest.xml
index d403acf90c..5a0b12e198 100644
--- a/doc/classes/HTTPRequest.xml
+++ b/doc/classes/HTTPRequest.xml
@@ -57,7 +57,7 @@
// Perform a POST request. The URL below returns JSON as of writing.
// Note: Don't make simultaneous requests using a single HTTPRequest node.
// The snippet below is provided for reference only.
- string body = new JSON().Stringify(new Godot.Collections.Dictionary
+ string body = new Json().Stringify(new Godot.Collections.Dictionary
{
{ "name", "Godette" }
});
@@ -69,14 +69,14 @@
}
// Called when the HTTP request is completed.
- private void HttpRequestCompleted(int result, int responseCode, string[] headers, byte[] body)
+ private void HttpRequestCompleted(long result, long responseCode, string[] headers, byte[] body)
{
- var json = new JSON();
- json.Parse(body.GetStringFromUTF8());
- var response = json.GetData() as Godot.Collections.Dictionary;
+ var json = new Json();
+ json.Parse(body.GetStringFromUtf8());
+ var response = json.GetData().AsGodotDictionary();
// Will print the user agent string used by the HTTPRequest node (as recognized by httpbin.org).
- GD.Print((response["headers"] as Godot.Collections.Dictionary)["User-Agent"]);
+ GD.Print((response["headers"].AsGodotDictionary())["User-Agent"]);
}
[/csharp]
[/codeblocks]
@@ -128,9 +128,9 @@
}
// Called when the HTTP request is completed.
- private void HttpRequestCompleted(int result, int responseCode, string[] headers, byte[] body)
+ private void HttpRequestCompleted(long result, long responseCode, string[] headers, byte[] body)
{
- if (result != (int)HTTPRequest.Result.Success)
+ if (result != (long)HTTPRequest.Result.Success)
{
GD.PushError("Image couldn't be downloaded. Try a different image.");
}
diff --git a/doc/classes/HashingContext.xml b/doc/classes/HashingContext.xml
index 7c2be6f817..5223cbf52f 100644
--- a/doc/classes/HashingContext.xml
+++ b/doc/classes/HashingContext.xml
@@ -8,7 +8,7 @@
The [enum HashType] enum shows the supported hashing algorithms.
[codeblocks]
[gdscript]
- const CHUNK_SIZE = 102
+ const CHUNK_SIZE = 1024
func hash_file(path):
# Check that file exists.
@@ -32,17 +32,16 @@
public void HashFile(string path)
{
- var ctx = new HashingContext();
- var file = new File();
- // Start a SHA-256 context.
- ctx.Start(HashingContext.HashType.Sha256);
// Check that file exists.
- if (!file.FileExists(path))
+ if (!FileAccess.FileExists(path))
{
return;
}
+ // Start a SHA-256 context.
+ var ctx = new HashingContext();
+ ctx.Start(HashingContext.HashType.Sha256);
// Open the file to hash.
- file.Open(path, File.ModeFlags.Read);
+ using var file = FileAccess.Open(path, FileAccess.ModeFlags.Read);
// Update the context after reading each chunk.
while (!file.EofReached())
{
@@ -51,8 +50,7 @@
// Get the computed hash.
byte[] res = ctx.Finish();
// Print the result as hex string and array.
-
- GD.PrintT(res.HexEncode(), res);
+ GD.PrintT(res.HexEncode(), (Variant)res);
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/InputEventMIDI.xml b/doc/classes/InputEventMIDI.xml
index 67e7ced2e8..e4ba380741 100644
--- a/doc/classes/InputEventMIDI.xml
+++ b/doc/classes/InputEventMIDI.xml
@@ -35,9 +35,9 @@
GD.Print(OS.GetConnectedMidiInputs());
}
- public override void _Input(InputEvent inputEvent)
+ public override void _Input(InputEvent @event)
{
- if (inputEvent is InputEventMIDI midiEvent)
+ if (@event is InputEventMIDI midiEvent)
{
PrintMIDIInfo(midiEvent);
}
@@ -46,14 +46,14 @@
private void PrintMIDIInfo(InputEventMIDI midiEvent)
{
GD.Print(midiEvent);
- GD.Print("Channel " + midiEvent.Channel);
- GD.Print("Message " + midiEvent.Message);
- GD.Print("Pitch " + midiEvent.Pitch);
- GD.Print("Velocity " + midiEvent.Velocity);
- GD.Print("Instrument " + midiEvent.Instrument);
- GD.Print("Pressure " + midiEvent.Pressure);
- GD.Print("Controller number: " + midiEvent.ControllerNumber);
- GD.Print("Controller value: " + midiEvent.ControllerValue);
+ GD.Print($"Channel {midiEvent.Channel}");
+ GD.Print($"Message {midiEvent.Message}");
+ GD.Print($"Pitch {midiEvent.Pitch}");
+ GD.Print($"Velocity {midiEvent.Velocity}");
+ GD.Print($"Instrument {midiEvent.Instrument}");
+ GD.Print($"Pressure {midiEvent.Pressure}");
+ GD.Print($"Controller number: {midiEvent.ControllerNumber}");
+ GD.Print($"Controller value: {midiEvent.ControllerValue}");
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/MainLoop.xml b/doc/classes/MainLoop.xml
index 674adb1772..260efb0eab 100644
--- a/doc/classes/MainLoop.xml
+++ b/doc/classes/MainLoop.xml
@@ -29,29 +29,28 @@
[/gdscript]
[csharp]
using Godot;
- using System;
- public class CustomMainLoop : MainLoop
+ public partial class CustomMainLoop : MainLoop
{
- public float TimeElapsed = 0;
+ private double _timeElapsed = 0;
public override void _Initialize()
{
GD.Print("Initialized:");
- GD.Print($" Starting Time: {TimeElapsed}");
+ GD.Print($" Starting Time: {_timeElapsed}");
}
- public override bool _Process(float delta)
+ public override bool _Process(double delta)
{
- TimeElapsed += delta;
+ _timeElapsed += delta;
// Return true to end the main loop.
- return Input.GetMouseButtonMask() != 0 || Input.IsKeyPressed((int)KeyList.Escape);
+ return Input.GetMouseButtonMask() != 0 || Input.IsKeyPressed(Key.Escape);
}
private void _Finalize()
{
GD.Print("Finalized:");
- GD.Print($" End Time: {TimeElapsed}");
+ GD.Print($" End Time: {_timeElapsed}");
}
}
[/csharp]
diff --git a/doc/classes/NavigationAgent2D.xml b/doc/classes/NavigationAgent2D.xml
index 6ae4dc4177..92fd8bcc6a 100644
--- a/doc/classes/NavigationAgent2D.xml
+++ b/doc/classes/NavigationAgent2D.xml
@@ -111,6 +111,21 @@
<member name="avoidance_enabled" type="bool" setter="set_avoidance_enabled" getter="get_avoidance_enabled" default="false">
If [code]true[/code] the agent is registered for an RVO avoidance callback on the [NavigationServer2D]. When [method NavigationAgent2D.set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector2 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it.
</member>
+ <member name="debug_enabled" type="bool" setter="set_debug_enabled" getter="get_debug_enabled" default="false">
+ If [code]true[/code] shows debug visuals for this agent.
+ </member>
+ <member name="debug_path_custom_color" type="Color" setter="set_debug_path_custom_color" getter="get_debug_path_custom_color" default="Color(1, 1, 1, 1)">
+ If [member debug_use_custom] is [code]true[/code] uses this color for this agent instead of global color.
+ </member>
+ <member name="debug_path_custom_line_width" type="float" setter="set_debug_path_custom_line_width" getter="get_debug_path_custom_line_width" default="1.0">
+ If [member debug_use_custom] is [code]true[/code] uses this line width for rendering paths for this agent instead of global line width.
+ </member>
+ <member name="debug_path_custom_point_size" type="float" setter="set_debug_path_custom_point_size" getter="get_debug_path_custom_point_size" default="4.0">
+ If [member debug_use_custom] is [code]true[/code] uses this rasterized point size for rendering path points for this agent instead of global point size.
+ </member>
+ <member name="debug_use_custom" type="bool" setter="set_debug_use_custom" getter="get_debug_use_custom" default="false">
+ If [code]true[/code] uses the defined [member debug_path_custom_color] for this agent instead of global color.
+ </member>
<member name="max_neighbors" type="int" setter="set_max_neighbors" getter="get_max_neighbors" default="10">
The maximum number of neighbors for the agent to consider.
</member>
diff --git a/doc/classes/NavigationAgent3D.xml b/doc/classes/NavigationAgent3D.xml
index a22cd6dd46..0ed11bc477 100644
--- a/doc/classes/NavigationAgent3D.xml
+++ b/doc/classes/NavigationAgent3D.xml
@@ -114,6 +114,18 @@
<member name="avoidance_enabled" type="bool" setter="set_avoidance_enabled" getter="get_avoidance_enabled" default="false">
If [code]true[/code] the agent is registered for an RVO avoidance callback on the [NavigationServer3D]. When [method NavigationAgent3D.set_velocity] is used and the processing is completed a [code]safe_velocity[/code] Vector3 is received with a signal connection to [signal velocity_computed]. Avoidance processing with many registered agents has a significant performance cost and should only be enabled on agents that currently require it.
</member>
+ <member name="debug_enabled" type="bool" setter="set_debug_enabled" getter="get_debug_enabled" default="false">
+ If [code]true[/code] shows debug visuals for this agent.
+ </member>
+ <member name="debug_path_custom_color" type="Color" setter="set_debug_path_custom_color" getter="get_debug_path_custom_color" default="Color(1, 1, 1, 1)">
+ If [member debug_use_custom] is [code]true[/code] uses this color for this agent instead of global color.
+ </member>
+ <member name="debug_path_custom_point_size" type="float" setter="set_debug_path_custom_point_size" getter="get_debug_path_custom_point_size" default="4.0">
+ If [member debug_use_custom] is [code]true[/code] uses this rasterized point size for rendering path points for this agent instead of global point size.
+ </member>
+ <member name="debug_use_custom" type="bool" setter="set_debug_use_custom" getter="get_debug_use_custom" default="false">
+ If [code]true[/code] uses the defined [member debug_path_custom_color] for this agent instead of global color.
+ </member>
<member name="ignore_y" type="bool" setter="set_ignore_y" getter="get_ignore_y" default="true">
Ignores collisions on the Y axis. Must be true to move on a horizontal plane.
</member>
diff --git a/doc/classes/NavigationServer2D.xml b/doc/classes/NavigationServer2D.xml
index 16f6de5238..7270a19b4d 100644
--- a/doc/classes/NavigationServer2D.xml
+++ b/doc/classes/NavigationServer2D.xml
@@ -528,5 +528,10 @@
Emitted when a navigation map is updated, when a region moves or is modified.
</description>
</signal>
+ <signal name="navigation_debug_changed">
+ <description>
+ Emitted when navigation debug settings are changed. Only available in debug builds.
+ </description>
+ </signal>
</signals>
</class>
diff --git a/doc/classes/Object.xml b/doc/classes/Object.xml
index e4607456ca..e30ff6be19 100644
--- a/doc/classes/Object.xml
+++ b/doc/classes/Object.xml
@@ -110,7 +110,7 @@
[/gdscript]
[csharp]
[Tool]
- public class MyNode2D : Node2D
+ public partial class MyNode2D : Node2D
{
private bool _holdingHammer;
@@ -433,9 +433,9 @@
var button = new Button();
// Option 1: In C#, we can use signals as events and connect with this idiomatic syntax:
button.ButtonDown += OnButtonDown;
- // Option 2: Object.Connect() with a constructed Callable from a method group.
+ // Option 2: GodotObject.Connect() with a constructed Callable from a method group.
button.Connect(Button.SignalName.ButtonDown, Callable.From(OnButtonDown));
- // Option 3: Object.Connect() with a constructed Callable using a target object and method name.
+ // Option 3: GodotObject.Connect() with a constructed Callable using a target object and method name.
button.Connect(Button.SignalName.ButtonDown, new Callable(this, MethodName.OnButtonDown));
}
@@ -700,10 +700,10 @@
sprite2d.is_class("Node3D") # Returns false
[/gdscript]
[csharp]
- var sprite2d = new Sprite2D();
- sprite2d.IsClass("Sprite2D"); // Returns true
- sprite2d.IsClass("Node"); // Returns true
- sprite2d.IsClass("Node3D"); // Returns false
+ var sprite2D = new Sprite2D();
+ sprite2D.IsClass("Sprite2D"); // Returns true
+ sprite2D.IsClass("Node"); // Returns true
+ sprite2D.IsClass("Node3D"); // Returns false
[/csharp]
[/codeblocks]
[b]Note:[/b] This method ignores [code]class_name[/code] declarations in the object's script.
@@ -747,10 +747,10 @@
player.SetScript(GD.Load("res://player.gd"));
player.Notification(NotificationEnterTree);
- // The call order is Object -&gt; Node -&gt; Node2D -&gt; player.gd.
+ // The call order is GodotObject -&gt; Node -&gt; Node2D -&gt; player.gd.
- player.notification(NotificationEnterTree, true);
- // The call order is player.gd -&gt; Node2D -&gt; Node -&gt; Object.
+ player.Notification(NotificationEnterTree, true);
+ // The call order is player.gd -&gt; Node2D -&gt; Node -&gt; GodotObject.
[/csharp]
[/codeblocks]
</description>
diff --git a/doc/classes/ProjectSettings.xml b/doc/classes/ProjectSettings.xml
index 95bd060fc6..e429759e93 100644
--- a/doc/classes/ProjectSettings.xml
+++ b/doc/classes/ProjectSettings.xml
@@ -528,9 +528,21 @@
<member name="debug/shapes/collision/shape_color" type="Color" setter="" getter="" default="Color(0, 0.6, 0.7, 0.42)">
Color of the collision shapes, visible when "Visible Collision Shapes" is enabled in the Debug menu.
</member>
+ <member name="debug/shapes/navigation/agent_path_color" type="Color" setter="" getter="" default="Color(1, 0, 0, 1)">
+ Color to display enabled navigation agent paths when an agent has debug enabled.
+ </member>
+ <member name="debug/shapes/navigation/agent_path_point_size" type="float" setter="" getter="" default="4.0">
+ Rasterized size (pixel) used to render navigation agent path points when an agent has debug enabled.
+ </member>
<member name="debug/shapes/navigation/edge_connection_color" type="Color" setter="" getter="" default="Color(1, 0, 1, 1)">
Color to display edge connections between navigation regions, visible when "Visible Navigation" is enabled in the Debug menu.
</member>
+ <member name="debug/shapes/navigation/enable_agent_paths" type="bool" setter="" getter="" default="true">
+ If enabled, displays navigation agent paths when an agent has debug enabled.
+ </member>
+ <member name="debug/shapes/navigation/enable_agent_paths_xray" type="bool" setter="" getter="" default="true">
+ If enabled, displays navigation agent paths through geometry when an agent has debug enabled.
+ </member>
<member name="debug/shapes/navigation/enable_edge_connections" type="bool" setter="" getter="" default="true">
If enabled, displays edge connections between navigation regions when "Visible Navigation" is enabled in the Debug menu.
</member>
@@ -1743,7 +1755,7 @@
[/gdscript]
[csharp]
// Set the default gravity strength to 980.
- PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2d().Space, PhysicsServer2D.AreaParameter.Gravity, 980);
+ PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2D().Space, PhysicsServer2D.AreaParameter.Gravity, 980);
[/csharp]
[/codeblocks]
</member>
@@ -1757,7 +1769,7 @@
[/gdscript]
[csharp]
// Set the default gravity direction to `Vector2(0, 1)`.
- PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2d().Space, PhysicsServer2D.AreaParameter.GravityVector, Vector2.Down)
+ PhysicsServer2D.AreaSetParam(GetViewport().FindWorld2D().Space, PhysicsServer2D.AreaParameter.GravityVector, Vector2.Down)
[/csharp]
[/codeblocks]
</member>
diff --git a/doc/classes/RichTextEffect.xml b/doc/classes/RichTextEffect.xml
index c01546524d..333d34d1b7 100644
--- a/doc/classes/RichTextEffect.xml
+++ b/doc/classes/RichTextEffect.xml
@@ -13,7 +13,7 @@
[/gdscript]
[csharp]
// The RichTextEffect will be usable like this: `[example]Some text[/example]`
- public string bbcode = "example";
+ string bbcode = "example";
[/csharp]
[/codeblocks]
[b]Note:[/b] As soon as a [RichTextLabel] contains at least one [RichTextEffect], it will continuously process the effect unless the project is paused. This may impact battery life negatively.
diff --git a/doc/classes/SceneTree.xml b/doc/classes/SceneTree.xml
index bf19ebc23a..6adb37a3f7 100644
--- a/doc/classes/SceneTree.xml
+++ b/doc/classes/SceneTree.xml
@@ -74,10 +74,10 @@
print("end")
[/gdscript]
[csharp]
- public async void SomeFunction()
+ public async Task SomeFunction()
{
GD.Print("start");
- await ToSignal(GetTree().CreateTimer(1.0f), "timeout");
+ await ToSignal(GetTree().CreateTimer(1.0f), SceneTreeTimer.SignalName.Timeout);
GD.Print("end");
}
[/csharp]
diff --git a/doc/classes/SceneTreeTimer.xml b/doc/classes/SceneTreeTimer.xml
index f28e65c5bf..42b070d7d9 100644
--- a/doc/classes/SceneTreeTimer.xml
+++ b/doc/classes/SceneTreeTimer.xml
@@ -14,10 +14,10 @@
print("Timer ended.")
[/gdscript]
[csharp]
- public async void SomeFunction()
+ public async Task SomeFunction()
{
GD.Print("Timer started.");
- await ToSignal(GetTree().CreateTimer(1.0f), "timeout");
+ await ToSignal(GetTree().CreateTimer(1.0f), SceneTreeTimer.SignalName.Timeout);
GD.Print("Timer ended.");
}
[/csharp]
diff --git a/doc/classes/Sprite2D.xml b/doc/classes/Sprite2D.xml
index 235fef0bdd..033dbf51f3 100644
--- a/doc/classes/Sprite2D.xml
+++ b/doc/classes/Sprite2D.xml
@@ -23,11 +23,11 @@
print("A click!")
[/gdscript]
[csharp]
- public override void _Input(InputEvent inputEvent)
+ public override void _Input(InputEvent @event)
{
- if (inputEvent is InputEventMouseButton inputEventMouse)
+ if (@event is InputEventMouseButton inputEventMouse)
{
- if (inputEventMouse.Pressed &amp;&amp; inputEventMouse.ButtonIndex == (int)ButtonList.Left)
+ if (inputEventMouse.Pressed &amp;&amp; inputEventMouse.ButtonIndex == MouseButton.Left)
{
if (GetRect().HasPoint(ToLocal(inputEventMouse.Position)))
{
diff --git a/doc/classes/StreamPeer.xml b/doc/classes/StreamPeer.xml
index f05b5f7dbf..969cbac57d 100644
--- a/doc/classes/StreamPeer.xml
+++ b/doc/classes/StreamPeer.xml
@@ -223,7 +223,7 @@
put_data("Hello world".to_utf8())
[/gdscript]
[csharp]
- PutData("Hello World".ToUTF8());
+ PutData("Hello World".ToUtf8());
[/csharp]
[/codeblocks]
</description>
diff --git a/doc/classes/SubViewport.xml b/doc/classes/SubViewport.xml
index 7020cae1de..bb76a82ef3 100644
--- a/doc/classes/SubViewport.xml
+++ b/doc/classes/SubViewport.xml
@@ -26,6 +26,7 @@
</member>
<member name="size" type="Vector2i" setter="set_size" getter="get_size" default="Vector2i(512, 512)">
The width and height of the sub-viewport. Must be set to a value greater than or equal to 2 pixels on both dimensions. Otherwise, nothing will be displayed.
+ [b]Note:[/b] If the parent node is a [SubViewportContainer] and its [member SubViewportContainer.stretch] is [code]true[/code], the viewport size cannot be changed manually.
</member>
<member name="size_2d_override" type="Vector2i" setter="set_size_2d_override" getter="get_size_2d_override" default="Vector2i(0, 0)">
The 2D size override of the sub-viewport. If either the width or height is [code]0[/code], the override is disabled.
diff --git a/doc/classes/SubViewportContainer.xml b/doc/classes/SubViewportContainer.xml
index 77aa7e3ff4..11137222a9 100644
--- a/doc/classes/SubViewportContainer.xml
+++ b/doc/classes/SubViewportContainer.xml
@@ -13,6 +13,7 @@
<members>
<member name="stretch" type="bool" setter="set_stretch" getter="is_stretch_enabled" default="false">
If [code]true[/code], the sub-viewport will be automatically resized to the control's size.
+ [b]Note:[/b] If [code]true[/code], this will prohibit changing [member SubViewport.size] of its children manually.
</member>
<member name="stretch_shrink" type="int" setter="set_stretch_shrink" getter="get_stretch_shrink" default="1">
Divides the sub-viewport's effective resolution by this value while preserving its scale. This can be used to speed up rendering.
diff --git a/doc/classes/Tween.xml b/doc/classes/Tween.xml
index 9bb92cf362..16e4ce3714 100644
--- a/doc/classes/Tween.xml
+++ b/doc/classes/Tween.xml
@@ -77,13 +77,13 @@
tween = create_tween()
[/gdscript]
[csharp]
- private Tween tween;
+ private Tween _tween;
public void Animate()
{
- if (tween != null)
- tween.Kill(); // Abort the previous animation
- tween = CreateTween();
+ if (_tween != null)
+ _tween.Kill(); // Abort the previous animation
+ _tween = CreateTween();
}
[/csharp]
[/codeblocks]
diff --git a/doc/classes/UDPServer.xml b/doc/classes/UDPServer.xml
index c3a3a49a80..8151ecb625 100644
--- a/doc/classes/UDPServer.xml
+++ b/doc/classes/UDPServer.xml
@@ -9,7 +9,8 @@
Below a small example of how it can be used:
[codeblocks]
[gdscript]
- class_name Server
+ # server_node.gd
+ class_name ServerNode
extends Node
var server := UDPServer.new()
@@ -34,35 +35,35 @@
pass # Do something with the connected peers.
[/gdscript]
[csharp]
+ // ServerNode.cs
using Godot;
- using System;
using System.Collections.Generic;
- public class Server : Node
+ public partial class ServerNode : Node
{
- public UDPServer Server = new UDPServer();
- public List&lt;PacketPeerUDP&gt; Peers = new List&lt;PacketPeerUDP&gt;();
+ private UdpServer _server = new UdpServer();
+ private List&lt;PacketPeerUdp&gt; _peers = new List&lt;PacketPeerUdp&gt;();
public override void _Ready()
{
- Server.Listen(4242);
+ _server.Listen(4242);
}
- public override void _Process(float delta)
+ public override void _Process(double delta)
{
- Server.Poll(); // Important!
- if (Server.IsConnectionAvailable())
+ _server.Poll(); // Important!
+ if (_server.IsConnectionAvailable())
{
- PacketPeerUDP peer = Server.TakeConnection();
+ PacketPeerUdp peer = _server.TakeConnection();
byte[] packet = peer.GetPacket();
- GD.Print($"Accepted Peer: {peer.GetPacketIp()}:{peer.GetPacketPort()}");
- GD.Print($"Received Data: {packet.GetStringFromUTF8()}");
+ GD.Print($"Accepted Peer: {peer.GetPacketIP()}:{peer.GetPacketPort()}");
+ GD.Print($"Received Data: {packet.GetStringFromUtf8()}");
// Reply so it knows we received the message.
peer.PutPacket(packet);
// Keep a reference so we can keep contacting the remote peer.
- Peers.Add(peer);
+ _peers.Add(peer);
}
- foreach (var peer in Peers)
+ foreach (var peer in _peers)
{
// Do something with the peers.
}
@@ -72,7 +73,8 @@
[/codeblocks]
[codeblocks]
[gdscript]
- class_name Client
+ # client_node.gd
+ class_name ClientNode
extends Node
var udp := PacketPeerUDP.new()
@@ -90,30 +92,30 @@
connected = true
[/gdscript]
[csharp]
+ // ClientNode.cs
using Godot;
- using System;
- public class Client : Node
+ public partial class ClientNode : Node
{
- public PacketPeerUDP Udp = new PacketPeerUDP();
- public bool Connected = false;
+ private PacketPeerUdp _udp = new PacketPeerUdp();
+ private bool _connected = false;
public override void _Ready()
{
- Udp.ConnectToHost("127.0.0.1", 4242);
+ _udp.ConnectToHost("127.0.0.1", 4242);
}
- public override void _Process(float delta)
+ public override void _Process(double delta)
{
- if (!Connected)
+ if (!_connected)
{
// Try to contact server
- Udp.PutPacket("The Answer Is..42!".ToUTF8());
+ _udp.PutPacket("The Answer Is..42!".ToUtf8());
}
- if (Udp.GetAvailablePacketCount() &gt; 0)
+ if (_udp.GetAvailablePacketCount() &gt; 0)
{
- GD.Print($"Connected: {Udp.GetPacket().GetStringFromUTF8()}");
- Connected = true;
+ GD.Print($"Connected: {_udp.GetPacket().GetStringFromUtf8()}");
+ _connected = true;
}
}
}
diff --git a/doc/classes/UndoRedo.xml b/doc/classes/UndoRedo.xml
index 6c151ef958..e43bceb941 100644
--- a/doc/classes/UndoRedo.xml
+++ b/doc/classes/UndoRedo.xml
@@ -27,11 +27,11 @@
undo_redo.commit_action()
[/gdscript]
[csharp]
- public UndoRedo UndoRedo;
+ private UndoRedo _undoRedo;
public override void _Ready()
{
- UndoRedo = GetUndoRedo(); // Method of EditorPlugin.
+ _undoRedo = GetUndoRedo(); // Method of EditorPlugin.
}
public void DoSomething()
@@ -47,12 +47,12 @@
private void OnMyButtonPressed()
{
var node = GetNode&lt;Node2D&gt;("MyNode2D");
- UndoRedo.CreateAction("Move the node");
- UndoRedo.AddDoMethod(this, MethodName.DoSomething);
- UndoRedo.AddUndoMethod(this, MethodName.UndoSomething);
- UndoRedo.AddDoProperty(node, Node2D.PropertyName.Position, new Vector2(100, 100));
- UndoRedo.AddUndoProperty(node, Node2D.PropertyName.Position, node.Position);
- UndoRedo.CommitAction();
+ _undoRedo.CreateAction("Move the node");
+ _undoRedo.AddDoMethod(new Callable(this, MethodName.DoSomething));
+ _undoRedo.AddUndoMethod(new Callable(this, MethodName.UndoSomething));
+ _undoRedo.AddDoProperty(node, "position", new Vector2(100, 100));
+ _undoRedo.AddUndoProperty(node, "position", node.Position);
+ _undoRedo.CommitAction();
}
[/csharp]
[/codeblocks]
diff --git a/modules/gdscript/doc_classes/@GDScript.xml b/modules/gdscript/doc_classes/@GDScript.xml
index cd837b3a91..32acad76aa 100644
--- a/modules/gdscript/doc_classes/@GDScript.xml
+++ b/modules/gdscript/doc_classes/@GDScript.xml
@@ -227,18 +227,6 @@
[/codeblock]
</description>
</method>
- <method name="str" qualifiers="vararg">
- <return type="String" />
- <description>
- Converts one or more arguments to a [String] in the best way possible.
- [codeblock]
- var a = [10, 20, 30]
- var b = str(a);
- len(a) # Returns 3
- len(b) # Returns 12
- [/codeblock]
- </description>
- </method>
<method name="type_exists">
<return type="bool" />
<param index="0" name="type" type="StringName" />
diff --git a/modules/gdscript/gdscript_utility_functions.cpp b/modules/gdscript/gdscript_utility_functions.cpp
index 10d83dcfe5..758b61bb31 100644
--- a/modules/gdscript/gdscript_utility_functions.cpp
+++ b/modules/gdscript/gdscript_utility_functions.cpp
@@ -112,28 +112,6 @@ struct GDScriptUtilityFunctionsDefinitions {
*r_ret = String(result);
}
- static inline void str(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
- if (p_arg_count < 1) {
- r_error.error = Callable::CallError::CALL_ERROR_TOO_FEW_ARGUMENTS;
- r_error.argument = 1;
- r_error.expected = 1;
- *r_ret = Variant();
- return;
- }
-
- String str;
- for (int i = 0; i < p_arg_count; i++) {
- String os = p_args[i]->operator String();
-
- if (i == 0) {
- str = os;
- } else {
- str += os;
- }
- }
- *r_ret = str;
- }
-
static inline void range(Variant *r_ret, const Variant **p_args, int p_arg_count, Callable::CallError &r_error) {
switch (p_arg_count) {
case 0: {
@@ -651,7 +629,6 @@ void GDScriptUtilityFunctions::register_functions() {
REGISTER_VARIANT_FUNC(convert, true, VARARG("what"), ARG("type", Variant::INT));
REGISTER_FUNC(type_exists, true, Variant::BOOL, ARG("type", Variant::STRING_NAME));
REGISTER_FUNC(_char, true, Variant::STRING, ARG("char", Variant::INT));
- REGISTER_VARARG_FUNC(str, true, Variant::STRING);
REGISTER_VARARG_FUNC(range, false, Variant::ARRAY);
REGISTER_CLASS_FUNC(load, false, "Resource", ARG("path", Variant::STRING));
REGISTER_FUNC(inst_to_dict, false, Variant::DICTIONARY, ARG("instance", Variant::OBJECT));
diff --git a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
index 8463403096..4610761bdb 100644
--- a/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
+++ b/modules/mono/glue/GodotSharp/GodotSharp/Core/Extensions/PackedSceneExtensions.cs
@@ -7,7 +7,7 @@ namespace Godot
/// <summary>
/// Instantiates the scene's node hierarchy, erroring on failure.
/// Triggers child scene instantiation(s). Triggers a
- /// <see cref="Node.NotificationInstanced"/> notification on the root node.
+ /// <see cref="Node.NotificationSceneInstantiated"/> notification on the root node.
/// </summary>
/// <seealso cref="InstantiateOrNull{T}(GenEditState)"/>
/// <exception cref="InvalidCastException">
@@ -23,7 +23,7 @@ namespace Godot
/// <summary>
/// Instantiates the scene's node hierarchy, returning <see langword="null"/> on failure.
/// Triggers child scene instantiation(s). Triggers a
- /// <see cref="Node.NotificationInstanced"/> notification on the root node.
+ /// <see cref="Node.NotificationSceneInstantiated"/> notification on the root node.
/// </summary>
/// <seealso cref="Instantiate{T}(GenEditState)"/>
/// <typeparam name="T">The type to cast to. Should be a descendant of <see cref="Node"/>.</typeparam>
diff --git a/scene/2d/navigation_agent_2d.cpp b/scene/2d/navigation_agent_2d.cpp
index e73b6e7e23..380a684c9b 100644
--- a/scene/2d/navigation_agent_2d.cpp
+++ b/scene/2d/navigation_agent_2d.cpp
@@ -108,6 +108,26 @@ void NavigationAgent2D::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "time_horizon", PROPERTY_HINT_RANGE, "0.1,10,0.01,suffix:s"), "set_time_horizon", "get_time_horizon");
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "max_speed", PROPERTY_HINT_RANGE, "0.1,10000,0.01,suffix:px/s"), "set_max_speed", "get_max_speed");
+#ifdef DEBUG_ENABLED
+ ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent2D::set_debug_enabled);
+ ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent2D::get_debug_enabled);
+ ClassDB::bind_method(D_METHOD("set_debug_use_custom", "enabled"), &NavigationAgent2D::set_debug_use_custom);
+ ClassDB::bind_method(D_METHOD("get_debug_use_custom"), &NavigationAgent2D::get_debug_use_custom);
+ ClassDB::bind_method(D_METHOD("set_debug_path_custom_color", "color"), &NavigationAgent2D::set_debug_path_custom_color);
+ ClassDB::bind_method(D_METHOD("get_debug_path_custom_color"), &NavigationAgent2D::get_debug_path_custom_color);
+ ClassDB::bind_method(D_METHOD("set_debug_path_custom_point_size", "point_size"), &NavigationAgent2D::set_debug_path_custom_point_size);
+ ClassDB::bind_method(D_METHOD("get_debug_path_custom_point_size"), &NavigationAgent2D::get_debug_path_custom_point_size);
+ ClassDB::bind_method(D_METHOD("set_debug_path_custom_line_width", "line_width"), &NavigationAgent2D::set_debug_path_custom_line_width);
+ ClassDB::bind_method(D_METHOD("get_debug_path_custom_line_width"), &NavigationAgent2D::get_debug_path_custom_line_width);
+
+ ADD_GROUP("Debug", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_enabled"), "set_debug_enabled", "get_debug_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_line_width", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_line_width", "get_debug_path_custom_line_width");
+#endif // DEBUG_ENABLED
+
ADD_SIGNAL(MethodInfo("path_changed"));
ADD_SIGNAL(MethodInfo("target_reached"));
ADD_SIGNAL(MethodInfo("waypoint_reached", PropertyInfo(Variant::DICTIONARY, "details")));
@@ -123,6 +143,12 @@ void NavigationAgent2D::_notification(int p_what) {
// cannot use READY as ready does not get called if Node is readded to SceneTree
set_agent_parent(get_parent());
set_physics_process_internal(true);
+
+#ifdef DEBUG_ENABLED
+ if (NavigationServer2D::get_singleton()->get_debug_enabled()) {
+ debug_path_dirty = true;
+ }
+#endif // DEBUG_ENABLED
} break;
case NOTIFICATION_PARENTED: {
@@ -165,6 +191,12 @@ void NavigationAgent2D::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
agent_parent = nullptr;
set_physics_process_internal(false);
+
+#ifdef DEBUG_ENABLED
+ if (debug_path_instance.is_valid()) {
+ RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, false);
+ }
+#endif // DEBUG_ENABLED
} break;
case NOTIFICATION_INTERNAL_PHYSICS_PROCESS: {
@@ -176,6 +208,12 @@ void NavigationAgent2D::_notification(int p_what) {
}
_check_distance_to_target();
}
+
+#ifdef DEBUG_ENABLED
+ if (debug_path_dirty) {
+ _update_debug_path();
+ }
+#endif // DEBUG_ENABLED
} break;
}
}
@@ -194,12 +232,25 @@ NavigationAgent2D::NavigationAgent2D() {
navigation_result = Ref<NavigationPathQueryResult2D>();
navigation_result.instantiate();
+
+#ifdef DEBUG_ENABLED
+ NavigationServer2D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed));
+#endif // DEBUG_ENABLED
}
NavigationAgent2D::~NavigationAgent2D() {
ERR_FAIL_NULL(NavigationServer2D::get_singleton());
NavigationServer2D::get_singleton()->free(agent);
agent = RID(); // Pointless
+
+#ifdef DEBUG_ENABLED
+ NavigationServer2D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent2D::_navigation_debug_changed));
+
+ ERR_FAIL_NULL(RenderingServer::get_singleton());
+ if (debug_path_instance.is_valid()) {
+ RenderingServer::get_singleton()->free(debug_path_instance);
+ }
+#endif // DEBUG_ENABLED
}
void NavigationAgent2D::set_avoidance_enabled(bool p_enabled) {
@@ -463,6 +514,9 @@ void NavigationAgent2D::update_navigation() {
}
NavigationServer2D::get_singleton()->query_path(navigation_query, navigation_result);
+#ifdef DEBUG_ENABLED
+ debug_path_dirty = true;
+#endif // DEBUG_ENABLED
navigation_finished = false;
navigation_path_index = 0;
emit_signal(SNAME("path_changed"));
@@ -549,3 +603,111 @@ void NavigationAgent2D::_check_distance_to_target() {
}
}
}
+
+////////DEBUG////////////////////////////////////////////////////////////
+
+#ifdef DEBUG_ENABLED
+void NavigationAgent2D::set_debug_enabled(bool p_enabled) {
+ debug_enabled = p_enabled;
+ debug_path_dirty = true;
+}
+
+bool NavigationAgent2D::get_debug_enabled() const {
+ return debug_enabled;
+}
+
+void NavigationAgent2D::set_debug_use_custom(bool p_enabled) {
+ debug_use_custom = p_enabled;
+ debug_path_dirty = true;
+}
+
+bool NavigationAgent2D::get_debug_use_custom() const {
+ return debug_use_custom;
+}
+
+void NavigationAgent2D::set_debug_path_custom_color(Color p_color) {
+ debug_path_custom_color = p_color;
+ debug_path_dirty = true;
+}
+
+Color NavigationAgent2D::get_debug_path_custom_color() const {
+ return debug_path_custom_color;
+}
+
+void NavigationAgent2D::set_debug_path_custom_point_size(float p_point_size) {
+ debug_path_custom_point_size = MAX(0.1, p_point_size);
+ debug_path_dirty = true;
+}
+
+float NavigationAgent2D::get_debug_path_custom_point_size() const {
+ return debug_path_custom_point_size;
+}
+
+void NavigationAgent2D::set_debug_path_custom_line_width(float p_line_width) {
+ debug_path_custom_line_width = p_line_width;
+ debug_path_dirty = true;
+}
+
+float NavigationAgent2D::get_debug_path_custom_line_width() const {
+ return debug_path_custom_line_width;
+}
+
+void NavigationAgent2D::_navigation_debug_changed() {
+ debug_path_dirty = true;
+}
+
+void NavigationAgent2D::_update_debug_path() {
+ if (!debug_path_dirty) {
+ return;
+ }
+ debug_path_dirty = false;
+
+ if (!debug_path_instance.is_valid()) {
+ debug_path_instance = RenderingServer::get_singleton()->canvas_item_create();
+ }
+
+ RenderingServer::get_singleton()->canvas_item_clear(debug_path_instance);
+
+ if (!(debug_enabled && NavigationServer2D::get_singleton()->get_debug_navigation_enable_agent_paths())) {
+ return;
+ }
+
+ if (!(agent_parent && agent_parent->is_inside_tree())) {
+ return;
+ }
+
+ RenderingServer::get_singleton()->canvas_item_set_parent(debug_path_instance, agent_parent->get_canvas());
+ RenderingServer::get_singleton()->canvas_item_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
+
+ const Vector<Vector2> &navigation_path = navigation_result->get_path();
+
+ if (navigation_path.size() <= 1) {
+ return;
+ }
+
+ Color debug_path_color = NavigationServer2D::get_singleton()->get_debug_navigation_agent_path_color();
+ if (debug_use_custom) {
+ debug_path_color = debug_path_custom_color;
+ }
+
+ Vector<Color> debug_path_colors;
+ debug_path_colors.resize(navigation_path.size());
+ debug_path_colors.fill(debug_path_color);
+
+ RenderingServer::get_singleton()->canvas_item_add_polyline(debug_path_instance, navigation_path, debug_path_colors, debug_path_custom_line_width, false);
+
+ float point_size = NavigationServer2D::get_singleton()->get_debug_navigation_agent_path_point_size();
+ float half_point_size = point_size * 0.5;
+
+ if (debug_use_custom) {
+ point_size = debug_path_custom_point_size;
+ half_point_size = debug_path_custom_point_size * 0.5;
+ }
+
+ for (int i = 0; i < navigation_path.size(); i++) {
+ const Vector2 &vert = navigation_path[i];
+ Rect2 path_point_rect = Rect2(vert.x - half_point_size, vert.y - half_point_size, point_size, point_size);
+ RenderingServer::get_singleton()->canvas_item_add_rect(debug_path_instance, path_point_rect, debug_path_color);
+ }
+}
+#endif // DEBUG_ENABLED
diff --git a/scene/2d/navigation_agent_2d.h b/scene/2d/navigation_agent_2d.h
index 9787bb1bdb..8f4a373327 100644
--- a/scene/2d/navigation_agent_2d.h
+++ b/scene/2d/navigation_agent_2d.h
@@ -74,6 +74,20 @@ class NavigationAgent2D : public Node {
// No initialized on purpose
uint32_t update_frame_id = 0;
+#ifdef DEBUG_ENABLED
+ bool debug_enabled = false;
+ bool debug_path_dirty = true;
+ RID debug_path_instance;
+ float debug_path_custom_point_size = 4.0;
+ float debug_path_custom_line_width = 1.0;
+ bool debug_use_custom = false;
+ Color debug_path_custom_color = Color(1.0, 1.0, 1.0, 1.0);
+
+private:
+ void _navigation_debug_changed();
+ void _update_debug_path();
+#endif // DEBUG_ENABLED
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -169,6 +183,23 @@ public:
PackedStringArray get_configuration_warnings() const override;
+#ifdef DEBUG_ENABLED
+ void set_debug_enabled(bool p_enabled);
+ bool get_debug_enabled() const;
+
+ void set_debug_use_custom(bool p_enabled);
+ bool get_debug_use_custom() const;
+
+ void set_debug_path_custom_color(Color p_color);
+ Color get_debug_path_custom_color() const;
+
+ void set_debug_path_custom_point_size(float p_point_size);
+ float get_debug_path_custom_point_size() const;
+
+ void set_debug_path_custom_line_width(float p_line_width);
+ float get_debug_path_custom_line_width() const;
+#endif // DEBUG_ENABLED
+
private:
void update_navigation();
void _request_repath();
diff --git a/scene/3d/navigation_agent_3d.cpp b/scene/3d/navigation_agent_3d.cpp
index 4aa6e61ec5..5db8611d72 100644
--- a/scene/3d/navigation_agent_3d.cpp
+++ b/scene/3d/navigation_agent_3d.cpp
@@ -120,6 +120,23 @@ void NavigationAgent3D::_bind_methods() {
ADD_SIGNAL(MethodInfo("link_reached", PropertyInfo(Variant::DICTIONARY, "details")));
ADD_SIGNAL(MethodInfo("navigation_finished"));
ADD_SIGNAL(MethodInfo("velocity_computed", PropertyInfo(Variant::VECTOR3, "safe_velocity")));
+
+#ifdef DEBUG_ENABLED
+ ClassDB::bind_method(D_METHOD("set_debug_enabled", "enabled"), &NavigationAgent3D::set_debug_enabled);
+ ClassDB::bind_method(D_METHOD("get_debug_enabled"), &NavigationAgent3D::get_debug_enabled);
+ ClassDB::bind_method(D_METHOD("set_debug_use_custom", "enabled"), &NavigationAgent3D::set_debug_use_custom);
+ ClassDB::bind_method(D_METHOD("get_debug_use_custom"), &NavigationAgent3D::get_debug_use_custom);
+ ClassDB::bind_method(D_METHOD("set_debug_path_custom_color", "color"), &NavigationAgent3D::set_debug_path_custom_color);
+ ClassDB::bind_method(D_METHOD("get_debug_path_custom_color"), &NavigationAgent3D::get_debug_path_custom_color);
+ ClassDB::bind_method(D_METHOD("set_debug_path_custom_point_size", "point_size"), &NavigationAgent3D::set_debug_path_custom_point_size);
+ ClassDB::bind_method(D_METHOD("get_debug_path_custom_point_size"), &NavigationAgent3D::get_debug_path_custom_point_size);
+
+ ADD_GROUP("Debug", "");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_enabled"), "set_debug_enabled", "get_debug_enabled");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "debug_use_custom"), "set_debug_use_custom", "get_debug_use_custom");
+ ADD_PROPERTY(PropertyInfo(Variant::COLOR, "debug_path_custom_color"), "set_debug_path_custom_color", "get_debug_path_custom_color");
+ ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "debug_path_custom_point_size", PROPERTY_HINT_RANGE, "1,50,1,suffix:px"), "set_debug_path_custom_point_size", "get_debug_path_custom_point_size");
+#endif // DEBUG_ENABLED
}
void NavigationAgent3D::_notification(int p_what) {
@@ -129,6 +146,12 @@ void NavigationAgent3D::_notification(int p_what) {
// cannot use READY as ready does not get called if Node is readded to SceneTree
set_agent_parent(get_parent());
set_physics_process_internal(true);
+
+#ifdef DEBUG_ENABLED
+ if (NavigationServer3D::get_singleton()->get_debug_enabled()) {
+ debug_path_dirty = true;
+ }
+#endif // DEBUG_ENABLED
} break;
case NOTIFICATION_PARENTED: {
@@ -151,6 +174,12 @@ void NavigationAgent3D::_notification(int p_what) {
case NOTIFICATION_EXIT_TREE: {
set_agent_parent(nullptr);
set_physics_process_internal(false);
+
+#ifdef DEBUG_ENABLED
+ if (debug_path_instance.is_valid()) {
+ RS::get_singleton()->instance_set_visible(debug_path_instance, false);
+ }
+#endif // DEBUG_ENABLED
} break;
case NOTIFICATION_PAUSED: {
@@ -182,6 +211,11 @@ void NavigationAgent3D::_notification(int p_what) {
}
_check_distance_to_target();
}
+#ifdef DEBUG_ENABLED
+ if (debug_path_dirty) {
+ _update_debug_path();
+ }
+#endif // DEBUG_ENABLED
} break;
}
}
@@ -201,12 +235,28 @@ NavigationAgent3D::NavigationAgent3D() {
navigation_result = Ref<NavigationPathQueryResult3D>();
navigation_result.instantiate();
+
+#ifdef DEBUG_ENABLED
+ NavigationServer3D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent3D::_navigation_debug_changed));
+#endif // DEBUG_ENABLED
}
NavigationAgent3D::~NavigationAgent3D() {
ERR_FAIL_NULL(NavigationServer3D::get_singleton());
NavigationServer3D::get_singleton()->free(agent);
agent = RID(); // Pointless
+
+#ifdef DEBUG_ENABLED
+ NavigationServer3D::get_singleton()->disconnect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationAgent3D::_navigation_debug_changed));
+
+ ERR_FAIL_NULL(RenderingServer::get_singleton());
+ if (debug_path_instance.is_valid()) {
+ RenderingServer::get_singleton()->free(debug_path_instance);
+ }
+ if (debug_path_mesh.is_valid()) {
+ RenderingServer::get_singleton()->free(debug_path_mesh->get_rid());
+ }
+#endif // DEBUG_ENABLED
}
void NavigationAgent3D::set_avoidance_enabled(bool p_enabled) {
@@ -480,6 +530,9 @@ void NavigationAgent3D::update_navigation() {
}
NavigationServer3D::get_singleton()->query_path(navigation_query, navigation_result);
+#ifdef DEBUG_ENABLED
+ debug_path_dirty = true;
+#endif // DEBUG_ENABLED
navigation_finished = false;
navigation_path_index = 0;
emit_signal(SNAME("path_changed"));
@@ -566,3 +619,130 @@ void NavigationAgent3D::_check_distance_to_target() {
}
}
}
+
+////////DEBUG////////////////////////////////////////////////////////////
+
+#ifdef DEBUG_ENABLED
+void NavigationAgent3D::set_debug_enabled(bool p_enabled) {
+ debug_enabled = p_enabled;
+ debug_path_dirty = true;
+}
+
+bool NavigationAgent3D::get_debug_enabled() const {
+ return debug_enabled;
+}
+
+void NavigationAgent3D::set_debug_use_custom(bool p_enabled) {
+ debug_use_custom = p_enabled;
+ debug_path_dirty = true;
+}
+
+bool NavigationAgent3D::get_debug_use_custom() const {
+ return debug_use_custom;
+}
+
+void NavigationAgent3D::set_debug_path_custom_color(Color p_color) {
+ debug_path_custom_color = p_color;
+ debug_path_dirty = true;
+}
+
+Color NavigationAgent3D::get_debug_path_custom_color() const {
+ return debug_path_custom_color;
+}
+
+void NavigationAgent3D::set_debug_path_custom_point_size(float p_point_size) {
+ debug_path_custom_point_size = p_point_size;
+ debug_path_dirty = true;
+}
+
+float NavigationAgent3D::get_debug_path_custom_point_size() const {
+ return debug_path_custom_point_size;
+}
+
+void NavigationAgent3D::_navigation_debug_changed() {
+ debug_path_dirty = true;
+}
+
+void NavigationAgent3D::_update_debug_path() {
+ if (!debug_path_dirty) {
+ return;
+ }
+ debug_path_dirty = false;
+
+ if (!debug_path_instance.is_valid()) {
+ debug_path_instance = RenderingServer::get_singleton()->instance_create();
+ }
+
+ if (!debug_path_mesh.is_valid()) {
+ debug_path_mesh = Ref<ArrayMesh>(memnew(ArrayMesh));
+ }
+
+ debug_path_mesh->clear_surfaces();
+
+ if (!(debug_enabled && NavigationServer3D::get_singleton()->get_debug_navigation_enable_agent_paths())) {
+ return;
+ }
+
+ if (!(agent_parent && agent_parent->is_inside_tree())) {
+ return;
+ }
+
+ const Vector<Vector3> &navigation_path = navigation_result->get_path();
+
+ if (navigation_path.size() <= 1) {
+ return;
+ }
+
+ Vector<Vector3> debug_path_lines_vertex_array;
+
+ for (int i = 0; i < navigation_path.size() - 1; i++) {
+ debug_path_lines_vertex_array.push_back(navigation_path[i]);
+ debug_path_lines_vertex_array.push_back(navigation_path[i + 1]);
+ }
+
+ Array debug_path_lines_mesh_array;
+ debug_path_lines_mesh_array.resize(Mesh::ARRAY_MAX);
+ debug_path_lines_mesh_array[Mesh::ARRAY_VERTEX] = debug_path_lines_vertex_array;
+
+ debug_path_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, debug_path_lines_mesh_array);
+
+ Ref<StandardMaterial3D> debug_agent_path_line_material = NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_line_material();
+ if (debug_use_custom) {
+ if (!debug_agent_path_line_custom_material.is_valid()) {
+ debug_agent_path_line_custom_material = debug_agent_path_line_material->duplicate();
+ }
+ debug_agent_path_line_custom_material->set_albedo(debug_path_custom_color);
+ debug_path_mesh->surface_set_material(0, debug_agent_path_line_custom_material);
+ } else {
+ debug_path_mesh->surface_set_material(0, debug_agent_path_line_material);
+ }
+
+ Vector<Vector3> debug_path_points_vertex_array;
+
+ for (int i = 0; i < navigation_path.size(); i++) {
+ debug_path_points_vertex_array.push_back(navigation_path[i]);
+ }
+
+ Array debug_path_points_mesh_array;
+ debug_path_points_mesh_array.resize(Mesh::ARRAY_MAX);
+ debug_path_points_mesh_array[Mesh::ARRAY_VERTEX] = debug_path_lines_vertex_array;
+
+ debug_path_mesh->add_surface_from_arrays(Mesh::PRIMITIVE_POINTS, debug_path_points_mesh_array);
+
+ Ref<StandardMaterial3D> debug_agent_path_point_material = NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_point_material();
+ if (debug_use_custom) {
+ if (!debug_agent_path_point_custom_material.is_valid()) {
+ debug_agent_path_point_custom_material = debug_agent_path_point_material->duplicate();
+ }
+ debug_agent_path_point_custom_material->set_albedo(debug_path_custom_color);
+ debug_agent_path_point_custom_material->set_point_size(debug_path_custom_point_size);
+ debug_path_mesh->surface_set_material(1, debug_agent_path_point_custom_material);
+ } else {
+ debug_path_mesh->surface_set_material(1, debug_agent_path_point_material);
+ }
+
+ RS::get_singleton()->instance_set_base(debug_path_instance, debug_path_mesh->get_rid());
+ RS::get_singleton()->instance_set_scenario(debug_path_instance, agent_parent->get_world_3d()->get_scenario());
+ RS::get_singleton()->instance_set_visible(debug_path_instance, agent_parent->is_visible_in_tree());
+}
+#endif // DEBUG_ENABLED
diff --git a/scene/3d/navigation_agent_3d.h b/scene/3d/navigation_agent_3d.h
index 12f83ce6a8..98bf395d7c 100644
--- a/scene/3d/navigation_agent_3d.h
+++ b/scene/3d/navigation_agent_3d.h
@@ -76,6 +76,22 @@ class NavigationAgent3D : public Node {
// No initialized on purpose
uint32_t update_frame_id = 0;
+#ifdef DEBUG_ENABLED
+ bool debug_enabled = false;
+ bool debug_path_dirty = true;
+ RID debug_path_instance;
+ Ref<ArrayMesh> debug_path_mesh;
+ float debug_path_custom_point_size = 4.0;
+ bool debug_use_custom = false;
+ Color debug_path_custom_color = Color(1.0, 1.0, 1.0, 1.0);
+ Ref<StandardMaterial3D> debug_agent_path_line_custom_material;
+ Ref<StandardMaterial3D> debug_agent_path_point_custom_material;
+
+private:
+ void _navigation_debug_changed();
+ void _update_debug_path();
+#endif // DEBUG_ENABLED
+
protected:
static void _bind_methods();
void _notification(int p_what);
@@ -181,6 +197,20 @@ public:
PackedStringArray get_configuration_warnings() const override;
+#ifdef DEBUG_ENABLED
+ void set_debug_enabled(bool p_enabled);
+ bool get_debug_enabled() const;
+
+ void set_debug_use_custom(bool p_enabled);
+ bool get_debug_use_custom() const;
+
+ void set_debug_path_custom_color(Color p_color);
+ Color get_debug_path_custom_color() const;
+
+ void set_debug_path_custom_point_size(float p_point_size);
+ float get_debug_path_custom_point_size() const;
+#endif // DEBUG_ENABLED
+
private:
void update_navigation();
void _request_repath();
diff --git a/scene/animation/animation_blend_tree.cpp b/scene/animation/animation_blend_tree.cpp
index 45f4f690b9..797999625b 100644
--- a/scene/animation/animation_blend_tree.cpp
+++ b/scene/animation/animation_blend_tree.cpp
@@ -800,6 +800,14 @@ Ref<Curve> AnimationNodeTransition::get_xfade_curve() const {
return xfade_curve;
}
+void AnimationNodeTransition::set_allow_transition_to_self(bool p_enable) {
+ allow_transition_to_self = p_enable;
+}
+
+bool AnimationNodeTransition::is_allow_transition_to_self() const {
+ return allow_transition_to_self;
+}
+
double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_external_seeking) {
String cur_transition_request = get_parameter(transition_request);
int cur_current_index = get_parameter(current_index);
@@ -815,20 +823,22 @@ double AnimationNodeTransition::process(double p_time, bool p_seek, bool p_is_ex
int new_idx = find_input(cur_transition_request);
if (new_idx >= 0) {
if (cur_current_index == new_idx) {
- // Transition to same state.
- restart = input_data[cur_current_index].reset;
- cur_prev_xfading = 0;
- set_parameter(prev_xfading, 0);
- cur_prev_index = -1;
- set_parameter(prev_index, -1);
+ if (allow_transition_to_self) {
+ // Transition to same state.
+ restart = input_data[cur_current_index].reset;
+ cur_prev_xfading = 0;
+ set_parameter(prev_xfading, 0);
+ cur_prev_index = -1;
+ set_parameter(prev_index, -1);
+ }
} else {
switched = true;
cur_prev_index = cur_current_index;
set_parameter(prev_index, cur_current_index);
+ cur_current_index = new_idx;
+ set_parameter(current_index, cur_current_index);
+ set_parameter(current_state, cur_transition_request);
}
- cur_current_index = new_idx;
- set_parameter(current_index, cur_current_index);
- set_parameter(current_state, cur_transition_request);
} else {
ERR_PRINT("No such input: '" + cur_transition_request + "'");
}
@@ -932,8 +942,12 @@ void AnimationNodeTransition::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_xfade_curve", "curve"), &AnimationNodeTransition::set_xfade_curve);
ClassDB::bind_method(D_METHOD("get_xfade_curve"), &AnimationNodeTransition::get_xfade_curve);
+ ClassDB::bind_method(D_METHOD("set_allow_transition_to_self", "enable"), &AnimationNodeTransition::set_allow_transition_to_self);
+ ClassDB::bind_method(D_METHOD("is_allow_transition_to_self"), &AnimationNodeTransition::is_allow_transition_to_self);
+
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "xfade_time", PROPERTY_HINT_RANGE, "0,120,0.01,suffix:s"), "set_xfade_time", "get_xfade_time");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "xfade_curve", PROPERTY_HINT_RESOURCE_TYPE, "Curve"), "set_xfade_curve", "get_xfade_curve");
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_transition_to_self"), "set_allow_transition_to_self", "is_allow_transition_to_self");
ADD_PROPERTY(PropertyInfo(Variant::INT, "input_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_ARRAY | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED, "Inputs,input_"), "set_input_count", "get_input_count");
}
diff --git a/scene/animation/animation_blend_tree.h b/scene/animation/animation_blend_tree.h
index 3c27edbf70..20f8e9b190 100644
--- a/scene/animation/animation_blend_tree.h
+++ b/scene/animation/animation_blend_tree.h
@@ -294,6 +294,7 @@ class AnimationNodeTransition : public AnimationNodeSync {
double xfade_time = 0.0;
Ref<Curve> xfade_curve;
+ bool allow_transition_to_self = false;
protected:
bool _get(const StringName &p_path, Variant &r_ret) const;
@@ -325,6 +326,9 @@ public:
void set_xfade_curve(const Ref<Curve> &p_curve);
Ref<Curve> get_xfade_curve() const;
+ void set_allow_transition_to_self(bool p_enable);
+ bool is_allow_transition_to_self() const;
+
double process(double p_time, bool p_seek, bool p_is_external_seeking) override;
AnimationNodeTransition();
diff --git a/scene/animation/animation_node_state_machine.cpp b/scene/animation/animation_node_state_machine.cpp
index 7fb831b3b2..ec28a5cca1 100644
--- a/scene/animation/animation_node_state_machine.cpp
+++ b/scene/animation/animation_node_state_machine.cpp
@@ -252,7 +252,7 @@ bool AnimationNodeStateMachinePlayback::_travel(AnimationNodeStateMachine *p_sta
path.clear(); //a new one will be needed
if (current == p_travel) {
- return false; // Will teleport oneself (restart).
+ return !p_state_machine->is_allow_transition_to_self();
}
Vector2 current_pos = p_state_machine->states[current].position;
@@ -813,6 +813,14 @@ void AnimationNodeStateMachine::replace_node(const StringName &p_name, Ref<Anima
p_node->connect("tree_changed", callable_mp(this, &AnimationNodeStateMachine::_tree_changed), CONNECT_REFERENCE_COUNTED);
}
+void AnimationNodeStateMachine::set_allow_transition_to_self(bool p_enable) {
+ allow_transition_to_self = p_enable;
+}
+
+bool AnimationNodeStateMachine::is_allow_transition_to_self() const {
+ return allow_transition_to_self;
+}
+
bool AnimationNodeStateMachine::can_edit_node(const StringName &p_name) const {
if (states.has(p_name)) {
return !(states[p_name].node->is_class("AnimationNodeStartState") || states[p_name].node->is_class("AnimationNodeEndState"));
@@ -1383,6 +1391,11 @@ void AnimationNodeStateMachine::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_graph_offset", "offset"), &AnimationNodeStateMachine::set_graph_offset);
ClassDB::bind_method(D_METHOD("get_graph_offset"), &AnimationNodeStateMachine::get_graph_offset);
+
+ ClassDB::bind_method(D_METHOD("set_allow_transition_to_self", "enable"), &AnimationNodeStateMachine::set_allow_transition_to_self);
+ ClassDB::bind_method(D_METHOD("is_allow_transition_to_self"), &AnimationNodeStateMachine::is_allow_transition_to_self);
+
+ ADD_PROPERTY(PropertyInfo(Variant::BOOL, "allow_transition_to_self"), "set_allow_transition_to_self", "is_allow_transition_to_self");
}
AnimationNodeStateMachine::AnimationNodeStateMachine() {
diff --git a/scene/animation/animation_node_state_machine.h b/scene/animation/animation_node_state_machine.h
index cf4d850aa6..5c2a4d6264 100644
--- a/scene/animation/animation_node_state_machine.h
+++ b/scene/animation/animation_node_state_machine.h
@@ -188,6 +188,7 @@ private:
};
HashMap<StringName, State> states;
+ bool allow_transition_to_self = false;
struct Transition {
StringName from;
@@ -254,6 +255,9 @@ public:
void remove_transition_by_index(const int p_transition);
void remove_transition(const StringName &p_from, const StringName &p_to);
+ void set_allow_transition_to_self(bool p_enable);
+ bool is_allow_transition_to_self() const;
+
bool can_edit_node(const StringName &p_name) const;
AnimationNodeStateMachine *get_prev_state_machine() const;
diff --git a/scene/gui/subviewport_container.cpp b/scene/gui/subviewport_container.cpp
index 7c1d2f95a9..f10e1c2cd1 100644
--- a/scene/gui/subviewport_container.cpp
+++ b/scene/gui/subviewport_container.cpp
@@ -85,7 +85,7 @@ void SubViewportContainer::set_stretch_shrink(int p_shrink) {
continue;
}
- c->set_size(get_size() / shrink);
+ c->set_size_force(get_size() / shrink);
}
queue_redraw();
@@ -116,7 +116,7 @@ void SubViewportContainer::_notification(int p_what) {
continue;
}
- c->set_size(get_size() / shrink);
+ c->set_size_force(get_size() / shrink);
}
} break;
diff --git a/scene/main/viewport.cpp b/scene/main/viewport.cpp
index b6bcbe04a3..fe82fed2f7 100644
--- a/scene/main/viewport.cpp
+++ b/scene/main/viewport.cpp
@@ -4114,9 +4114,26 @@ Viewport::~Viewport() {
/////////////////////////////////
void SubViewport::set_size(const Size2i &p_size) {
- _set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
+ _internal_set_size(p_size);
+}
+void SubViewport::set_size_force(const Size2i &p_size) {
+ // Use only for setting the size from the parent SubViewportContainer with enabled stretch mode.
+ // Don't expose function to scripting.
+ _internal_set_size(p_size, true);
+}
+
+void SubViewport::_internal_set_size(const Size2i &p_size, bool p_force) {
SubViewportContainer *c = Object::cast_to<SubViewportContainer>(get_parent());
+ if (!p_force && c && c->is_stretch_enabled()) {
+#ifdef DEBUG_ENABLED
+ WARN_PRINT("Can't change the size of a `SubViewport` with a `SubViewportContainer` parent that has `stretch` enabled. Set `SubViewportContainer.stretch` to `false` to allow changing the size manually.");
+#endif // DEBUG_ENABLED
+ return;
+ }
+
+ _set_size(p_size, _get_size_2d_override(), Rect2i(), _stretch_transform(), true);
+
if (c) {
c->update_minimum_size();
}
diff --git a/scene/main/viewport.h b/scene/main/viewport.h
index e081013fde..2a4ddc422f 100644
--- a/scene/main/viewport.h
+++ b/scene/main/viewport.h
@@ -754,6 +754,8 @@ private:
ClearMode clear_mode = CLEAR_MODE_ALWAYS;
bool size_2d_override_stretch = false;
+ void _internal_set_size(const Size2i &p_size, bool p_force = false);
+
protected:
static void _bind_methods();
virtual DisplayServer::WindowID get_window_id() const override;
@@ -763,6 +765,7 @@ protected:
public:
void set_size(const Size2i &p_size);
Size2i get_size() const;
+ void set_size_force(const Size2i &p_size);
void set_size_2d_override(const Size2i &p_size);
Size2i get_size_2d_override() const;
diff --git a/servers/navigation_server_2d.cpp b/servers/navigation_server_2d.cpp
index 2e4087c1de..85ba8ed431 100644
--- a/servers/navigation_server_2d.cpp
+++ b/servers/navigation_server_2d.cpp
@@ -207,6 +207,30 @@ void NavigationServer2D::set_debug_navigation_enable_edge_connections(const bool
bool NavigationServer2D::get_debug_navigation_enable_edge_connections() const {
return NavigationServer3D::get_singleton()->get_debug_navigation_enable_edge_connections();
}
+
+void NavigationServer2D::set_debug_navigation_agent_path_color(const Color &p_color) {
+ NavigationServer3D::get_singleton()->set_debug_navigation_agent_path_color(p_color);
+}
+
+Color NavigationServer2D::get_debug_navigation_agent_path_color() const {
+ return NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_color();
+}
+
+void NavigationServer2D::set_debug_navigation_enable_agent_paths(const bool p_value) {
+ NavigationServer3D::get_singleton()->set_debug_navigation_enable_agent_paths(p_value);
+}
+
+bool NavigationServer2D::get_debug_navigation_enable_agent_paths() const {
+ return NavigationServer3D::get_singleton()->get_debug_navigation_enable_agent_paths();
+}
+
+void NavigationServer2D::set_debug_navigation_agent_path_point_size(float p_point_size) {
+ NavigationServer3D::get_singleton()->set_debug_navigation_agent_path_point_size(p_point_size);
+}
+
+float NavigationServer2D::get_debug_navigation_agent_path_point_size() const {
+ return NavigationServer3D::get_singleton()->get_debug_navigation_agent_path_point_size();
+}
#endif // DEBUG_ENABLED
void NavigationServer2D::_bind_methods() {
@@ -286,14 +310,26 @@ void NavigationServer2D::_bind_methods() {
ClassDB::bind_method(D_METHOD("free_rid", "rid"), &NavigationServer2D::free);
ADD_SIGNAL(MethodInfo("map_changed", PropertyInfo(Variant::RID, "map")));
+
+ ADD_SIGNAL(MethodInfo("navigation_debug_changed"));
}
NavigationServer2D::NavigationServer2D() {
singleton = this;
ERR_FAIL_COND_MSG(!NavigationServer3D::get_singleton(), "The Navigation3D singleton should be initialized before the 2D one.");
NavigationServer3D::get_singleton()->connect("map_changed", callable_mp(this, &NavigationServer2D::_emit_map_changed));
+
+#ifdef DEBUG_ENABLED
+ NavigationServer3D::get_singleton()->connect(SNAME("navigation_debug_changed"), callable_mp(this, &NavigationServer2D::_emit_navigation_debug_changed_signal));
+#endif // DEBUG_ENABLED
}
+#ifdef DEBUG_ENABLED
+void NavigationServer2D::_emit_navigation_debug_changed_signal() {
+ emit_signal(SNAME("navigation_debug_changed"));
+}
+#endif // DEBUG_ENABLED
+
NavigationServer2D::~NavigationServer2D() {
singleton = nullptr;
}
diff --git a/servers/navigation_server_2d.h b/servers/navigation_server_2d.h
index cd18476182..746389404b 100644
--- a/servers/navigation_server_2d.h
+++ b/servers/navigation_server_2d.h
@@ -254,6 +254,20 @@ public:
void set_debug_navigation_enable_edge_connections(const bool p_value);
bool get_debug_navigation_enable_edge_connections() const;
+
+ void set_debug_navigation_agent_path_color(const Color &p_color);
+ Color get_debug_navigation_agent_path_color() const;
+
+ void set_debug_navigation_enable_agent_paths(const bool p_value);
+ bool get_debug_navigation_enable_agent_paths() const;
+
+ void set_debug_navigation_agent_path_point_size(float p_point_size);
+ float get_debug_navigation_agent_path_point_size() const;
+#endif // DEBUG_ENABLED
+
+#ifdef DEBUG_ENABLED
+private:
+ void _emit_navigation_debug_changed_signal();
#endif // DEBUG_ENABLED
};
diff --git a/servers/navigation_server_3d.cpp b/servers/navigation_server_3d.cpp
index 8f2cff0e04..70897ae75c 100644
--- a/servers/navigation_server_3d.cpp
+++ b/servers/navigation_server_3d.cpp
@@ -159,6 +159,7 @@ NavigationServer3D::NavigationServer3D() {
debug_navigation_geometry_face_disabled_color = GLOBAL_DEF("debug/shapes/navigation/geometry_face_disabled_color", Color(0.5, 0.5, 0.5, 0.4));
debug_navigation_link_connection_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_color", Color(1.0, 0.5, 1.0, 1.0));
debug_navigation_link_connection_disabled_color = GLOBAL_DEF("debug/shapes/navigation/link_connection_disabled_color", Color(0.5, 0.5, 0.5, 1.0));
+ debug_navigation_agent_path_color = GLOBAL_DEF("debug/shapes/navigation/agent_path_color", Color(1.0, 0.0, 0.0, 1.0));
debug_navigation_enable_edge_connections = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections", true);
debug_navigation_enable_edge_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_edge_connections_xray", true);
@@ -168,6 +169,11 @@ NavigationServer3D::NavigationServer3D() {
debug_navigation_enable_link_connections = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections", true);
debug_navigation_enable_link_connections_xray = GLOBAL_DEF("debug/shapes/navigation/enable_link_connections_xray", true);
+ debug_navigation_enable_agent_paths = GLOBAL_DEF("debug/shapes/navigation/enable_agent_paths", true);
+ debug_navigation_enable_agent_paths_xray = GLOBAL_DEF("debug/shapes/navigation/enable_agent_paths_xray", true);
+
+ debug_navigation_agent_path_point_size = GLOBAL_DEF("debug/shapes/navigation/agent_path_point_size", 4.0);
+
if (Engine::get_singleton()->is_editor_hint()) {
// enable NavigationServer3D when in Editor or else navigation mesh edge connections are invisible
// on runtime tests SceneTree has "Visible Navigation" set and main iteration takes care of this
@@ -329,6 +335,42 @@ Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_link_connection
return debug_navigation_link_connections_disabled_material;
}
+Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_agent_path_line_material() {
+ if (debug_navigation_agent_path_line_material.is_valid()) {
+ return debug_navigation_agent_path_line_material;
+ }
+
+ Ref<StandardMaterial3D> material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ material->set_albedo(debug_navigation_agent_path_color);
+ if (debug_navigation_enable_agent_paths_xray) {
+ material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true);
+ }
+ material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MAX - 2);
+
+ debug_navigation_agent_path_line_material = material;
+ return debug_navigation_agent_path_line_material;
+}
+
+Ref<StandardMaterial3D> NavigationServer3D::get_debug_navigation_agent_path_point_material() {
+ if (debug_navigation_agent_path_point_material.is_valid()) {
+ return debug_navigation_agent_path_point_material;
+ }
+
+ Ref<StandardMaterial3D> material = Ref<StandardMaterial3D>(memnew(StandardMaterial3D));
+ material->set_shading_mode(StandardMaterial3D::SHADING_MODE_UNSHADED);
+ material->set_albedo(debug_navigation_agent_path_color);
+ material->set_flag(StandardMaterial3D::FLAG_USE_POINT_SIZE, true);
+ material->set_point_size(debug_navigation_agent_path_point_size);
+ if (debug_navigation_enable_agent_paths_xray) {
+ material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, true);
+ }
+ material->set_render_priority(StandardMaterial3D::RENDER_PRIORITY_MAX - 2);
+
+ debug_navigation_agent_path_point_material = material;
+ return debug_navigation_agent_path_point_material;
+}
+
void NavigationServer3D::set_debug_navigation_edge_connection_color(const Color &p_color) {
debug_navigation_edge_connection_color = p_color;
if (debug_navigation_edge_connections_material.is_valid()) {
@@ -406,6 +448,31 @@ Color NavigationServer3D::get_debug_navigation_link_connection_disabled_color()
return debug_navigation_link_connection_disabled_color;
}
+void NavigationServer3D::set_debug_navigation_agent_path_point_size(float p_point_size) {
+ debug_navigation_agent_path_point_size = MAX(0.1, p_point_size);
+ if (debug_navigation_agent_path_point_material.is_valid()) {
+ debug_navigation_agent_path_point_material->set_point_size(debug_navigation_agent_path_point_size);
+ }
+}
+
+float NavigationServer3D::get_debug_navigation_agent_path_point_size() const {
+ return debug_navigation_agent_path_point_size;
+}
+
+void NavigationServer3D::set_debug_navigation_agent_path_color(const Color &p_color) {
+ debug_navigation_agent_path_color = p_color;
+ if (debug_navigation_agent_path_line_material.is_valid()) {
+ debug_navigation_agent_path_line_material->set_albedo(debug_navigation_agent_path_color);
+ }
+ if (debug_navigation_agent_path_point_material.is_valid()) {
+ debug_navigation_agent_path_point_material->set_albedo(debug_navigation_agent_path_color);
+ }
+}
+
+Color NavigationServer3D::get_debug_navigation_agent_path_color() const {
+ return debug_navigation_agent_path_color;
+}
+
void NavigationServer3D::set_debug_navigation_enable_edge_connections(const bool p_value) {
debug_navigation_enable_edge_connections = p_value;
debug_dirty = true;
@@ -494,6 +561,37 @@ void NavigationServer3D::set_debug_enabled(bool p_enabled) {
bool NavigationServer3D::get_debug_enabled() const {
return debug_enabled;
}
+
+void NavigationServer3D::set_debug_navigation_enable_agent_paths(const bool p_value) {
+ if (debug_navigation_enable_agent_paths != p_value) {
+ debug_dirty = true;
+ }
+
+ debug_navigation_enable_agent_paths = p_value;
+
+ if (debug_dirty) {
+ call_deferred("_emit_navigation_debug_changed_signal");
+ }
+}
+
+bool NavigationServer3D::get_debug_navigation_enable_agent_paths() const {
+ return debug_navigation_enable_agent_paths;
+}
+
+void NavigationServer3D::set_debug_navigation_enable_agent_paths_xray(const bool p_value) {
+ debug_navigation_enable_agent_paths_xray = p_value;
+ if (debug_navigation_agent_path_line_material.is_valid()) {
+ debug_navigation_agent_path_line_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, debug_navigation_enable_agent_paths_xray);
+ }
+ if (debug_navigation_agent_path_point_material.is_valid()) {
+ debug_navigation_agent_path_point_material->set_flag(StandardMaterial3D::FLAG_DISABLE_DEPTH_TEST, debug_navigation_enable_agent_paths_xray);
+ }
+}
+
+bool NavigationServer3D::get_debug_navigation_enable_agent_paths_xray() const {
+ return debug_navigation_enable_agent_paths_xray;
+}
+
#endif // DEBUG_ENABLED
///////////////////////////////////////////////////////
diff --git a/servers/navigation_server_3d.h b/servers/navigation_server_3d.h
index 9c468d1b10..bc4bdf2a30 100644
--- a/servers/navigation_server_3d.h
+++ b/servers/navigation_server_3d.h
@@ -287,6 +287,9 @@ private:
Color debug_navigation_geometry_face_disabled_color = Color(0.5, 0.5, 0.5, 0.4);
Color debug_navigation_link_connection_color = Color(1.0, 0.5, 1.0, 1.0);
Color debug_navigation_link_connection_disabled_color = Color(0.5, 0.5, 0.5, 1.0);
+ Color debug_navigation_agent_path_color = Color(1.0, 0.0, 0.0, 1.0);
+
+ float debug_navigation_agent_path_point_size = 4.0;
bool debug_navigation_enable_edge_connections = true;
bool debug_navigation_enable_edge_connections_xray = true;
@@ -295,6 +298,8 @@ private:
bool debug_navigation_enable_geometry_face_random_color = true;
bool debug_navigation_enable_link_connections = true;
bool debug_navigation_enable_link_connections_xray = true;
+ bool debug_navigation_enable_agent_paths = true;
+ bool debug_navigation_enable_agent_paths_xray = true;
Ref<StandardMaterial3D> debug_navigation_geometry_edge_material;
Ref<StandardMaterial3D> debug_navigation_geometry_face_material;
@@ -304,6 +309,9 @@ private:
Ref<StandardMaterial3D> debug_navigation_link_connections_material;
Ref<StandardMaterial3D> debug_navigation_link_connections_disabled_material;
+ Ref<StandardMaterial3D> debug_navigation_agent_path_line_material;
+ Ref<StandardMaterial3D> debug_navigation_agent_path_point_material;
+
public:
void set_debug_enabled(bool p_enabled);
bool get_debug_enabled() const;
@@ -329,6 +337,9 @@ public:
void set_debug_navigation_link_connection_disabled_color(const Color &p_color);
Color get_debug_navigation_link_connection_disabled_color() const;
+ void set_debug_navigation_agent_path_color(const Color &p_color);
+ Color get_debug_navigation_agent_path_color() const;
+
void set_debug_navigation_enable_edge_connections(const bool p_value);
bool get_debug_navigation_enable_edge_connections() const;
@@ -350,6 +361,15 @@ public:
void set_debug_navigation_enable_link_connections_xray(const bool p_value);
bool get_debug_navigation_enable_link_connections_xray() const;
+ void set_debug_navigation_enable_agent_paths(const bool p_value);
+ bool get_debug_navigation_enable_agent_paths() const;
+
+ void set_debug_navigation_enable_agent_paths_xray(const bool p_value);
+ bool get_debug_navigation_enable_agent_paths_xray() const;
+
+ void set_debug_navigation_agent_path_point_size(float p_point_size);
+ float get_debug_navigation_agent_path_point_size() const;
+
Ref<StandardMaterial3D> get_debug_navigation_geometry_face_material();
Ref<StandardMaterial3D> get_debug_navigation_geometry_edge_material();
Ref<StandardMaterial3D> get_debug_navigation_geometry_face_disabled_material();
@@ -357,6 +377,9 @@ public:
Ref<StandardMaterial3D> get_debug_navigation_edge_connections_material();
Ref<StandardMaterial3D> get_debug_navigation_link_connections_material();
Ref<StandardMaterial3D> get_debug_navigation_link_connections_disabled_material();
+
+ Ref<StandardMaterial3D> get_debug_navigation_agent_path_line_material();
+ Ref<StandardMaterial3D> get_debug_navigation_agent_path_point_material();
#endif // DEBUG_ENABLED
};