How to use C# 8.0 with Godot 3.3.2?

I am trying to use the System.Range and System.Index classes with new C# v8.0 construct, see (here). But, I cannot make it work. I have tried under Windows with .NET 5.0 and under Ubuntu with Mono 6 but I got the same result:

First I have changed the .csproj file like that:

<Project Sdk="Godot.NET.Sdk/3.3.0">
  <PropertyGroup>
    <TargetFramework>net472</TargetFramework>
    <LangVersion>8.0</LangVersion>
  </PropertyGroup>
</Project>

Note the <LangVersion> set at 8.0. With that parameter, I can now build the project with this kind of snippet:

int() nb = {1, 2, 3};
GD.Print(nb(1..2));

But at runtime, I got this error:
Predefined type 'System.Range' is not defined or imported


EDIT: To answer the comments.

@aimo:
I had to add using System.Runtime to make the project able to build.

@Theraot:
I had tried to change target framework to .net5.0 (that was only possible on Windows). The project was still able to build but the error at runtime was different:

E 0:00:01.563   debug_send_unhandled_exception_error: System.TypeLoadException: Could not resolve type with token 01000010 from typeref (expected class 'System.Range' in assembly 'System.Runtime, Version=5.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a')
  <C++ Error>   Unhandled exception
  <C++ Source>  modules/mono/mono_gd/gd_mono_utils.cpp:423 @ debug_send_unhandled_exception_error()

But this answer made me think that the Mono assemblies used at runtime needs net472.

Another hint is that an important Godot project that claims to use C# v8.0, the beautiful Thrive, sets net472 and 8.0 in their config file (see here)

Godot distance between 3d and 2d nodes

If you want the position of a 3D object on screen, you can do the following:

var position_2d = get_viewport().get_camera().unproject_position(position_3d)

That is, we use the camera projection to get the 3D position into screen coordinates with Camera.unproject_position which takes a Vector3 and returns Vector2. Why is that unproject and not project? Don’t know.

However, we need a Camera to do that. Luckily Viewport.get_camera returns the current 3D Camera. Why is there not a 2D counterpart? Don’t know.

And of course, to use get_camera we need a Viewport. We can get the Viewport the node belongs to with Node.get_viewport.


Of course, once you have the 2D position on the screen, you can use distance_to to find the distance to any Control on the screen, or whatever you need.

godot – Orthogonal Camera Clip/Hide part of 3D model

Move the Camera away.

I’m not suggesting to move the CameraRig, as the CameraRig is moved by code. Instead change the (local) transform of the Camera. Which is relative to its its parent (i.e. the CameraRig).

Even though the Camera is using an orthogonal projection. It still has a position in the world, and things behind the Camera get clipped. Remember that the near plane is always in front of the Camera.

Thus, pull the Camera away. Position it distant enough that everything that should be visible is visible.

That, of course, is no way around objects getting close to the Camera anyway. You can try setting objects materials with “Distance Fade” to handle that.

godot – Is there a way to run a tool script without attaching it to a node in the scene tree?

In this answer I present a few approaches to run code in the editor. The first one is pretty much what you are already doing. If that is an option for you, it is an option for you.

The second is using EditorScript. Which technically accomplishes the “without attaching it to a node in the scene tree” requirement. But it is limited in what it can do.

The third is using EditorPlugin. Which solves the “run a tool script on project load” requirement. Except, oh, surprise, the Godot IDE has a scene tree, which is not the scene tree of the game. I believe that EditorPlugin is what you want.

Well, I suppose there is another way: Writing a Godot Module (with C++), which require building Godot from source to include. See Compiling.


tool script

As you are aware, you can run GDScript in the IDE by making script a tool script (using the tool keyword). And you can check Engine.editor_hint to know when the code is running in the IDE.

Following that idea, you can have tool script, where check Engine.editor_hint is true and then instance there whatever you want to run only on the editor. If what you instanced there, is only instanced thereā€¦ Well, you can forgo further checking.

And yes, I suppose you can have it remove itself.


EditorScript

Create a new script that inherits from EditorScript. Make sure it is a tool script. Give it a _run function:

tool
extends EditorScript

func _run():
    print("Hello from the Godot Editor!")

This script runs from the Script Editor. With the script open, go to the File menu, and select Run. You can also use secondary click on the script on the Scripts Panel (on the left of the Script Editor) and select Run in the contextual menu.


EditorPlugin

Go to the Project menu, then Project Settings, on the Plugin tab, click create.

It will open a dialog asking about the details of your plugin. At minimum give it a Name (first field), a subfolder (second field) and a Script Name (last field). You can leave the rest blank (and even edit it later).

It will generate a script that looks like this:

tool
extends EditorPlugin

func _enter_tree() -> void:
    pass

func _exit_tree() -> void:
    pass

This script runs on the editor only. You can enable it and disable it on the Plugin tab of the Project Settings (where you create it). And yes, this is how you make plugins/addons for Godot.

When you enable it (or when you load a project where it is enabled) it will run _enter_tree. Similarly when disabling (or unloading a project where it is enabled) it will run _exit_tree.

To be clear, these will not run when you run the game (because, again, this script runs on the editor only).

Reminder: The Godot UI is made with Godot. It has a scene tree.

The EditorPlugin API will give you access to more parts of the IDE that you usually would.

Refer to Editor plugins and plugin folder of the official godot-demo-projects repository (on Github).

mouse – In Godot, how to make the cursor change shape when hovering over an Area2D?

I have several Area2Ds around the scene, and I need to make the cursor into a pointing hand whenever I hover over them. I tried this:

func _ready():
    connect("mouse_entered", self, "mouse_entered")
    connect("mouse_exited", self, "mouse_exited")
    
func mouse_entered():
    Input.set_default_cursor_shape (Input.CURSOR_POINTING_HAND )
    
func mouse_exited():
    Input.set_default_cursor_shape (Input.CURSOR_ARROW )

But this doesn’t work as intended when there are several overlapping zones. Whenever the cursor leaves one of the zones, it turns into an arrow, even if it’s still inside a different zone. How to make it reliably change into a hand when over a zone?

godot – How signals work when Node2D is queue_freed?

The simple solution is to not emit the signal if the node is queued for deletion:

func __on_screen_exited() -> void:
    if !is_queued_for_deletion():
        emit_signal("unvisible")

Note that this is happening before the node is freed. Using queue_free ensure all the steps needed to remove the Node safely happen between frames.

After the Node is removed from the Scene, Godot will disconnect signals from it, and then disconnect signals to it, then finally release the Node.

At the point you get this notification, the Node has disappeared because it is removed from the scene, but it has not been disconnected yet.


You are, of course, reloading the scene, which causes the loop:

func _reset_level() -> void:
    print("reset")
    get_tree().reload_current_scene()

Presumably, if you are running on a debug mode where there is no player, then the removal of the player should not cause the scene to reload. Thus:

func _ready() -> void:
    if debug_no_player:
        player.queue_free()
    else:
        player.connect("unvisible", self, "_reset_level")

Although, I’d argue for making the player its own scene and instance it (and connect its signals) only if debug_no_player is false, instead of removing the player if debug_no_player is true.

godot – How to know if an overriden method calls its super method or not?

I’m not an expert in gdscript/godot, but here is what I presume:

_ready being a “core” function acts similarly as a constructor. Typically (at least with a language like c++), when a new object is created, the most-parent constructor is called first, to make sure that the object is constructed when the child classes’ constructor is called. The child not yet being constructed, if the function foo is called in the parent’s constructor, it’s the parent class’s foo that will be called.

Although we have similarities here, it’s not exactly the same.

_ready being a utility function, it will be called in order of the most parent’s to the most child by the framework, making sure that what’s “initialized” in the parents is initialized for the children–just like a constructor. However, unlike it would be the case in a constructor, all the objects having already been created, the “most overridden” function foo will hide all those that have been defined its ancestors.

Taking a look at the source code, there are multiple occurrences where a “child” _Ready() will call it’s base._Ready() as the first thing it does, so it appears this is consistent with the theory.


How to know if an overriden method calls its super method or not?

It’s probably safe to say that the “top ancestor” will have it’s _ready function called first, down to the “most overridden” _ready function. This behaviour will likely be the same for _init, although I have not found anything relevant about it.

For the other cases, the normal “hiding” will be done, and you’ll call the the “most overridden” foo function.