Impressive explanation! I already know about raycasting from the screen to world space, but there is no such helper function in godot. And you made me understand about this better!
👍Thank you so much for this. I had so much trouble finding anything explaining how to do this. Your method still works in Godot 4. I only had to change the last line with intersect_ray() because it requires a PhysicsRayQueryParameters3D parameter now - _Godot_ _3.4_ var rayArray = spaceState.instesect_ray(rayOrigin, rayEnd) _Godot_ _4_ var rayArray = spaceState.intersect_ray(PhysicsRayQueryParameters3D.create(rayOrigin, rayEnd))
I like that you make tutorials on stuff that no one else has. Even if it's sometimes out of my range, I'm guaranteed to learn something new. Thank you. Do you know how to find the mouse position and or get input from the mouse when it is outside the game window?
Thank you! Unfortunately, I have a problem with this solution. I can't post a link here I think... I've described the problem on stackoverflow, it can be found by `Godot doesn't handle a ray-casting with HTerrain properly` search
awesome tutorial. really helped with my top down. But ive got another problem i just cant figure out and its stressing me out. Is there a chance someone could explain to me how i can use this method along with a button to instantiate an object on my mouse position? ive got the ray, ive got the button, i just dont get how i can make the button instantiate at the mouse position. help is veeeery appreciated!
Thank you so much for your tutorial, it was really helpful! I just have a question, is there any way to make the player look at the cursor without having to cast a ray until it collides? For example, in a platformer game ambientated in the void, the player can't look at the mouse when it doesn't collide with a platform and it is in the void (which in this case doesn't have any object with collision whatsoever). Is there any alternative solution?
@@FinePointCGI You were right! I found on a thread a way to do it: Basically you do the same thing, but instead of using the sphere as a collider you use a plane: _var dropPlane = Plane(Vector3(0, 1, 0), 0)_ _var position3D = dropPlane.intersects_ray(_ _$SpringArm/Camera.project_ray_origin(get_viewport().get_mouse_position()),_ _$SpringArm/Camera.project_ray_normal(get_viewport().get_mouse_position()))_ Anyway, thanks again for the help!
I swear there used to be a build-in function for this... but I must be losing my mind. Anyway, thanks pointman! I was able to implement this thing after 20 seconds of watching because thats when I paused your vid to type over the function that does all of this. I was also going to thank you for uploading this code to github but it seems you've put a version up there explicitly with that bit missing, so uhhhhh yeah. EDIT: Found the master branch, my man!
ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh fucking love you!!!!!!! Waste 3 hours trying shit math until I find your video and solve it in five minutes. Nice tutorial
I tried this today for a 3D cursor, and for some reason it zooms from its position on the ground toward the camera when I do it. Is this caused by multiple collision points or what?
For C# it is really unusual that IntersectRay returns an untyped dictionary of values instead of a type-safe object. I love Godot but things like this makes me appreciate Unity's C# API a lot more :/
Yeah that's definitely one of the big issues that I have with c# support in Godot. They do a lot of extended classes and a lot of variance which makes things really hard to work with... It's gotten a lot better with .net 6 but I feel like the community may need to ask for better c# support...
@@FinePointCGI using Godot; using System; public class YourScriptName : KinematicBody { private float gravity = 20; private float speed = 10; private Camera camera; public override void _Ready() { camera = GetActiveCamera(GetTree().Root) as Camera; } public override void _Process(float delta) { Vector3 vector = new Vector3(0, 0, 0); if (Input.IsActionPressed("ui_up")) vector.z = -1; if (Input.IsActionPressed("ui_down")) vector.z = 1; if (Input.IsActionPressed("ui_left")) vector.x = -1; if (Input.IsActionPressed("ui_right")) vector.x = 1; vector = vector.Normalized() * speed; vector.y -= gravity; MoveAndSlide(vector, Vector3.Up); // Rotate the KinematicBody to look at the mouse position LookAt(ScreenpointToRay(), Vector3.Up); } private Camera GetActiveCamera(Node node) { if (node.IsClass("Camera") && node.IsVisibleInTree()) return node as Camera; foreach (Node child in node.GetChildren()) { Camera camera = GetActiveCamera(child); if (camera != null) return camera; } return null; } private Vector3 ScreenpointToRay() { PhysicsDirectSpaceState spaceState = GetWorld().DirectSpaceState; Vector2 mousePos = GetViewport().GetMousePosition(); if (camera != null) { Vector3 rayOrigin = camera.ProjectRayOrigin(mousePos); Vector3 rayEnd = rayOrigin + camera.ProjectRayNormal(mousePos) * 2000; Godot.Collections.Array rayArray = spaceState.IntersectRay(rayOrigin, rayEnd); if (rayArray.Count > 0 && rayArray["collider"] != null) return (Vector3)rayArray["position"]; } return Vector3.Zero; } } my camera is not rotation properly with this code can you tell me the issue
Hey can you help me ! Question: how to refill life count in android while game is not open? Is there any background timer in godot which runs after the game is quit ? Thanks
There isn't a timer however you can get system time and write it to a file and then check that time on load to see if enough time has passed and then refill their lives.
Hello, This is a great video again. I would suggest you a new video content: integrate GameMonetize SDK to Godot. It would be helpful for online game developer.
@@FinePointCGI 3.4 and here is my code: extends KinematicBody var gravity = 20 var speed = 10 var camera : Camera func _ready(): camera = get_active_camera(get_tree().root) as Camera pass func _process(delta): var vector = Vector3(0, 0, 0) if Input.is_action_pressed("ui_up"): vector.z = -1 if Input.is_action_pressed("ui_down"): vector.z = 1 if Input.is_action_pressed("ui_left"): vector.x = -1 if Input.is_action_pressed("ui_right"): vector.x = 1
vector = vector.normalized() * speed vector.y -= gravity move_and_slide(vector, Vector3.UP) # Rotate the KinematicBody to look at the mouse position #look_at(ScreenpointtoRay(), Vector3.UP) func get_active_camera(node: Node) -> Camera: if node.is_class("Camera") and node.is_visible_in_tree(): return node as Camera for child in node.get_children(): var camera = get_active_camera(child) if camera != null: return camera return null func ScreenpointtoRay() -> Vector3: var spaceState = get_world().direct_space_state var mousePos = get_viewport().get_mouse_position() if camera != null: var rayOrigin = camera.project_ray_origin(mousePos) var rayEnd = rayOrigin + camera.project_ray_normal(mousePos) * 200 var rayArray = spaceState.intersect_ray(rayOrigin, rayEnd)
if rayArray.size() > 0 and rayArray["collider"] != null: return rayArray["position"]
not all tutorials are made for people who dont know how to code. These tutorials are made for people who know how to code and need references for techniques within a certain context.
Impressive explanation! I already know about raycasting from the screen to world space, but there is no such helper function in godot. And you made me understand about this better!
👍Thank you so much for this. I had so much trouble finding anything explaining how to do this. Your method still works in Godot 4. I only had to change the last line with intersect_ray() because it requires a PhysicsRayQueryParameters3D parameter now -
_Godot_ _3.4_
var rayArray = spaceState.instesect_ray(rayOrigin, rayEnd)
_Godot_ _4_
var rayArray = spaceState.intersect_ray(PhysicsRayQueryParameters3D.create(rayOrigin, rayEnd))
thank you, you came up right after I find the create method.
you guys are God sent thanks!
I love you
I'm sorry @battikh battikh I think TH-cam ate your comment!
I like that you make tutorials on stuff that no one else has. Even if it's sometimes out of my range, I'm guaranteed to learn something new. Thank you.
Do you know how to find the mouse position and or get input from the mouse when it is outside the game window?
That is not possible it's not tracked by Godot at that point so if it's out of the game window it's gone from Godot's world if that makes sense
@@FinePointCGI Bummer... But, good to know.. I suppose the same is true for screenshots? Can I capture the desktop or windows outside the game window?
Yeah you can't as far as I know unless you maximize the window and then somehow do a passthrough.
How can we do this without hitting a 3d object in my game
Thank you! Unfortunately, I have a problem with this solution. I can't post a link here I think... I've described the problem on stackoverflow, it can be found by `Godot doesn't handle a ray-casting with HTerrain properly` search
Would you mind doing a beginner tutorial when godot 4 comes out
I plan to! I'm going to (hopefully) start a from scratch series once it gets feature complete and is stable.
@@FinePointCGI Thank you
awesome tutorial. really helped with my top down. But ive got another problem i just cant figure out and its stressing me out.
Is there a chance someone could explain to me how i can use this method along with a button to instantiate an object on my mouse position?
ive got the ray, ive got the button, i just dont get how i can make the button instantiate at the mouse position. help is veeeery appreciated!
Thank you so much for your tutorial, it was really helpful! I just have a question, is there any way to make the player look at the cursor without having to cast a ray until it collides? For example, in a platformer game ambientated in the void, the player can't look at the mouse when it doesn't collide with a platform and it is in the void (which in this case doesn't have any object with collision whatsoever). Is there any alternative solution?
What I would do is wrap the world with a invisible sphere.. I'm not sure if there would be a way around that.
@@FinePointCGI You were right! I found on a thread a way to do it:
Basically you do the same thing, but instead of using the sphere as a collider you use a plane:
_var dropPlane = Plane(Vector3(0, 1, 0), 0)_
_var position3D = dropPlane.intersects_ray(_
_$SpringArm/Camera.project_ray_origin(get_viewport().get_mouse_position()),_
_$SpringArm/Camera.project_ray_normal(get_viewport().get_mouse_position()))_
Anyway, thanks again for the help!
Oh that makes great sense! No need to use a sphere when you can just use a plane!
I swear there used to be a build-in function for this... but I must be losing my mind. Anyway, thanks pointman! I was able to implement this thing after 20 seconds of watching because thats when I paused your vid to type over the function that does all of this.
I was also going to thank you for uploading this code to github but it seems you've put a version up there explicitly with that bit missing, so uhhhhh yeah.
EDIT: Found the master branch, my man!
Hey Man i need help. everything else is working except for the look_at(ScreenPointToRay(), Vector3.UP)
ahhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh fucking love you!!!!!!!
Waste 3 hours trying shit math until I find your video and solve it in five minutes.
Nice tutorial
Thank you!
Hey thanks! Im glad it worked for you!
Hello, it doesn't work in Godot 4
Hey I'm updating this I hope to have it out Monday!
I tried this today for a 3D cursor, and for some reason it zooms from its position on the ground toward the camera when I do it. Is this caused by multiple collision points or what?
Take the collision off the 3D cursor, or change its layer and add a layer mask to the raycast to the ground.
How can I stop looking at the mouse intensively,
It works but the character flip
Yes this is genuine hack and works as promised in my case. Thank you very much.
For C# it is really unusual that IntersectRay returns an untyped dictionary of values instead of a type-safe object. I love Godot but things like this makes me appreciate Unity's C# API a lot more :/
Yeah that's definitely one of the big issues that I have with c# support in Godot. They do a lot of extended classes and a lot of variance which makes things really hard to work with... It's gotten a lot better with .net 6 but I feel like the community may need to ask for better c# support...
@@FinePointCGI using Godot;
using System;
public class YourScriptName : KinematicBody
{
private float gravity = 20;
private float speed = 10;
private Camera camera;
public override void _Ready()
{
camera = GetActiveCamera(GetTree().Root) as Camera;
}
public override void _Process(float delta)
{
Vector3 vector = new Vector3(0, 0, 0);
if (Input.IsActionPressed("ui_up"))
vector.z = -1;
if (Input.IsActionPressed("ui_down"))
vector.z = 1;
if (Input.IsActionPressed("ui_left"))
vector.x = -1;
if (Input.IsActionPressed("ui_right"))
vector.x = 1;
vector = vector.Normalized() * speed;
vector.y -= gravity;
MoveAndSlide(vector, Vector3.Up);
// Rotate the KinematicBody to look at the mouse position
LookAt(ScreenpointToRay(), Vector3.Up);
}
private Camera GetActiveCamera(Node node)
{
if (node.IsClass("Camera") && node.IsVisibleInTree())
return node as Camera;
foreach (Node child in node.GetChildren())
{
Camera camera = GetActiveCamera(child);
if (camera != null)
return camera;
}
return null;
}
private Vector3 ScreenpointToRay()
{
PhysicsDirectSpaceState spaceState = GetWorld().DirectSpaceState;
Vector2 mousePos = GetViewport().GetMousePosition();
if (camera != null)
{
Vector3 rayOrigin = camera.ProjectRayOrigin(mousePos);
Vector3 rayEnd = rayOrigin + camera.ProjectRayNormal(mousePos) * 2000;
Godot.Collections.Array rayArray = spaceState.IntersectRay(rayOrigin, rayEnd);
if (rayArray.Count > 0 && rayArray["collider"] != null)
return (Vector3)rayArray["position"];
}
return Vector3.Zero;
}
}
my camera is not rotation properly with this code can you tell me the issue
Hey can you help me !
Question: how to refill life count in android while game is not open? Is there any background timer in godot which runs after the game is quit ?
Thanks
There isn't a timer however you can get system time and write it to a file and then check that time on load to see if enough time has passed and then refill their lives.
@@FinePointCGI Thank you!!!
That was helpful for me!
@@FinePointCGI can you share me the code??
My code for all of my projects are on GitHub github.com/finepointcgi/Point-to-ray-Tutorial/tree/master
Any chance we can get an updated version of this for C#?
here:
using Godot;
using System;
public class YourScriptName : KinematicBody
{
private float gravity = 20;
private float speed = 10;
private Camera camera;
public override void _Ready()
{
camera = GetActiveCamera(GetTree().Root) as Camera;
}
public override void _Process(float delta)
{
Vector3 vector = new Vector3(0, 0, 0);
if (Input.IsActionPressed("ui_up"))
vector.z = -1;
if (Input.IsActionPressed("ui_down"))
vector.z = 1;
if (Input.IsActionPressed("ui_left"))
vector.x = -1;
if (Input.IsActionPressed("ui_right"))
vector.x = 1;
vector = vector.Normalized() * speed;
vector.y -= gravity;
MoveAndSlide(vector, Vector3.Up);
// Rotate the KinematicBody to look at the mouse position
LookAt(ScreenpointToRay(), Vector3.Up);
}
private Camera GetActiveCamera(Node node)
{
if (node.IsClass("Camera") && node.IsVisibleInTree())
return node as Camera;
foreach (Node child in node.GetChildren())
{
Camera camera = GetActiveCamera(child);
if (camera != null)
return camera;
}
return null;
}
private Vector3 ScreenpointToRay()
{
PhysicsDirectSpaceState spaceState = GetWorld().DirectSpaceState;
Vector2 mousePos = GetViewport().GetMousePosition();
if (camera != null)
{
Vector3 rayOrigin = camera.ProjectRayOrigin(mousePos);
Vector3 rayEnd = rayOrigin + camera.ProjectRayNormal(mousePos) * 2000;
Godot.Collections.Array rayArray = spaceState.IntersectRay(rayOrigin, rayEnd);
if (rayArray.Count > 0 && rayArray["collider"] != null)
return (Vector3)rayArray["position"];
}
return Vector3.Zero;
}
}
Hello, This is a great video again. I would suggest you a new video content: integrate GameMonetize SDK to Godot. It would be helpful for online game developer.
I have added it to my trello list!
not working properly for me
What's it doing? What version of godot do you have
@@FinePointCGI 3.4 and here is my code:
extends KinematicBody
var gravity = 20
var speed = 10
var camera : Camera
func _ready():
camera = get_active_camera(get_tree().root) as Camera
pass
func _process(delta):
var vector = Vector3(0, 0, 0)
if Input.is_action_pressed("ui_up"):
vector.z = -1
if Input.is_action_pressed("ui_down"):
vector.z = 1
if Input.is_action_pressed("ui_left"):
vector.x = -1
if Input.is_action_pressed("ui_right"):
vector.x = 1
vector = vector.normalized() * speed
vector.y -= gravity
move_and_slide(vector, Vector3.UP)
# Rotate the KinematicBody to look at the mouse position
#look_at(ScreenpointtoRay(), Vector3.UP)
func get_active_camera(node: Node) -> Camera:
if node.is_class("Camera") and node.is_visible_in_tree():
return node as Camera
for child in node.get_children():
var camera = get_active_camera(child)
if camera != null:
return camera
return null
func ScreenpointtoRay() -> Vector3:
var spaceState = get_world().direct_space_state
var mousePos = get_viewport().get_mouse_position()
if camera != null:
var rayOrigin = camera.project_ray_origin(mousePos)
var rayEnd = rayOrigin + camera.project_ray_normal(mousePos) * 200
var rayArray = spaceState.intersect_ray(rayOrigin, rayEnd)
if rayArray.size() > 0 and rayArray["collider"] != null:
return rayArray["position"]
return Vector3.ZERO
love you
ᵖʳᵒᵐᵒˢᵐ
Tested the code and 99% of the time the ray does not hit anything, might want to cover other requirements on what the ray needs.
pleaseDontUseCamelCaseInGDScriptItsSuperAwful
I_dont_use_snake_case_it_is_super_awful_to_type.
Though it is pretty good for readability
Your explanation is lackluster you keep typing code but don't explain everything that you are doing in code
not all tutorials are made for people who dont know how to code. These tutorials are made for people who know how to code and need references for techniques within a certain context.
Thank you!