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’
If(rayCast.IsColliding() && rayCast.GetCollider() is Node selectedObj)
if (selectedObj.IsInGroup("ally_units")) { // TODO: Select unit SelectUnit(selectedObj); }
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?