C# get node from raycast

Godot Version

4.3 stable

Question

So I’m trying to do simple 3D RTS game on godot. And I need player to somehow select units. I decided to use raycast for it (ofc), but it won’t work as I meant to.

1st attempt:


	public override void _Process(double delta) {
		if (Input.IsActionPressed("camera_select_unit")) {
			if (rayCast.IsColliding()) {
				var selectedObj = (Node)rayCast.GetCollider(); // ??
				if (selNode.IsInGroup("ally_units")) {
					// TODO: Select unit
					SelectUnit(selNode);
				}
				
			}
		}
	}

This results me a lot of NativeCalls errors every second.

2nd attempt:


	public override void _Process(double delta) {
		if (Input.IsActionPressed("camera_select_unit")) {
			if (rayCast.IsColliding()) {
				var selectedObj = rayCast.GetCollider(); // ??
				if (selectedObj is Node) {
					if (selectedObj.IsInGroup("ally_units")) {
						// TODO: Select unit
						SelectUnit(selectedObj);
					}
				}
				
			}
		}
	}

And this gives me error like ‘can’t convert Godot.GodotObject into Godot.Node’

Try like this


If(rayCast.IsColliding() && rayCast.GetCollider() is Node  selectedObj)
if (selectedObj.IsInGroup("ally_units")) { 						// TODO: Select unit 						SelectUnit(selectedObj); 					}

Ps I writing on phone style can be litte off

I don’t know what the cause of your issue is. I just ran the following code, and it works as expected:

public partial class RayCastNodeTest : RayCast3D
{
	public override void _PhysicsProcess(double delta)
	{
		RayCast3D ray = this;

		if (ray.IsColliding())
		{
			var selectedObj = ray.GetCollider(); // ??
			if (selectedObj is Node n)
			{
				GD.Print($"Ray hit node {n.Name}");
			}
		}
	}
}

I tried running this code using both _Process() and _PhysicsProcess() – they both worked. That said, do remember that any physics-related systems should be run in a physics-related call such as _PhysicsProcess() or _IntegrateForces().

I also tried using the syntax: (Node)selectedObj. This worked as well.

Is it possible that neither of your code snippets are correct code?

1st attempt:
Here you define a local variable selectedObj in which you cast the collision object, but you don’t use it in the condition of your if-statement. Instead, you use selNode for the condition and the parameter of the SelectUnit() call. Why?

2nd attempt:
Here you’re simply not casting the selectedObj variable; you’re just conditionally checking its type in the condition of one of your if-statements. Therefore, selectedObj remains a GodotObject. Try using

if (selectedObj is Node n)

instead of

if (selectedObj is Node)

This nifty shorthand defines a variable that stores a casted version of your variable – in this case, the casted version is stored in the n variable.


I hope that helps. Let me know if you have any questions.

Oh, seems like my problem was with input actions. i basically forgot to add the action bind.
but, another questuion: how to raycast from mouse position and get the first intersected object?