so i need to do 5 checks in order to get the correct position? im thinking of putting the crosshair just back to dead center so i can do a simple raycast from camera

It's not 5 checks, it's one line of code:

var screen_coord = get_viewport_transform() * (get_global_transform() * local_pos)

@DJM said: guess i wont be using godot afterall :'( cant get my animations to import correctly in the engine. tried fbx, collada, gltf. everything screws up my skinning and animation tried to workaround and import them in blender first, they look fine there. even blenders' exporters dont work when importing. shame

I'm not sure if someone else told you the solution but, what you could do is separate the animations for the guns and in the hands in blender. After getting both the gun and hands in Godot, you can use a Bone Attachment node to connect the gun to the hand rig. If you want the animation for the gun animation and the hands animation to be one, you can just copy the animation tracks for one animation and then paste it into the other. Hopes still help. I feel your pain.

@cybereality said: It's not 5 checks, it's one line of code:

var screen_coord = get_viewport_transform() * (get_global_transform() * local_pos)

ok could u be more specific with an example for my setup please?> @Audiobellum said:

I'm not sure if someone else told you the solution but, what you could do is separate the animations for the guns and in the hands in blender. After getting both the gun and hands in Godot, you can use a Bone Attachment node to connect the gun to the hand rig. If you want the animation for the gun animation and the hands animation to be one, you can just copy the animation tracks for one animation and then paste it into the other. Hopes still help. I feel your pain. ive allready fixed it by switching to blender and using glb export with nla tracks, works fine now.

Actually, you might just be able to do this:

var trans = cross_hair.get_global_transform_with_canvas()
var screen_pos = Vector2(trans.x, trans.y)
# feed screen_pos into the ray cast instead of mouse

@cybereality said: Actually, you might just be cause to do this:

var trans = cross_hair.get_global_transform_with_canvas()
var screen_pos = Vector2(trans.x, trans.y)
# feed screen_pos into the ray cast instead of mouse

cross_hair is a node path to the texture rect right?

Yes, cross_hair was an example name, it can be any item that inherits from CanvasItem (such as a control node).

@cybereality said: Yes, cross_hair was an example name, it can be any item that inherits from CanvasItem (such as a control node).

tnx, will try it out

@cybereality said: Yes, cross_hair was an example name, it can be any item that inherits from CanvasItem (such as a control node).

i get invalid call non existant 'vector2' constructor

func firebullet():
	var trans = reticle.get_global_transform_with_canvas()
	# error non existant 'vector2' constructor>
	var screen_pos = Vector2(trans.x, trans.y)
	# feed screen_pos into the ray cast instead of mouse
	var camera = self
	var from = camera.project_ray_origin(screen_pos)
	var to = from + camera.project_ray_normal(screen_pos) * ray_length
	# what goes here to detect collision?

how to detect the collision point after the raycast? also ,why are some elements of my weapon node in the inspector in yellow? this is since alpha 8

When assigning values from other nodes based on nodepaths such as you do in var trans = reticle.get_global_transform_with_canvas() make sure to check that the reticle exists in scenetree first:

var trans

if is_inside_tree(reticle):
    trans = reticle.get_global_transform_with_canvas()

See if that doesn't help.

The should be the way to use Vector2. Maybe print out the values and see if they look right.

print("trans x: ", trans.x)
print("trans y: ", trans.y)

@cybereality said: The should be the way to use Vector2. Maybe print out the values and see if they look right.

print("trans x: ", trans.x)
print("trans y: ", trans.y)

it prints trans x: (1, 0) trans y : ( 0, 1)

Sorry, my code was incorrect. You can do this:

var screen_pos = reticle.get_global_transform_with_canvas().origin

@cybereality said: Sorry, my code was incorrect. You can do this:

var screen_pos = reticle.get_global_transform_with_canvas().origin

ok tnx! no errors no more how do i obtain the hit point and hit normal?

func firebullet():

var screen_pos = reticle.get_global_transform_with_canvas().origin var camera = self var from = camera.project_ray_origin(screen_pos) var to = from + camera.project_ray_normal(screen_pos) * ray_length #how to get hit point and hitnormal data?

I like the dark art, and the 3d ambiance.

@ami7mina said: I like the dark art, and the 3d ambiance.

tnx! exactly what im aiming for

This is the code that will get the collider. You might have to change a bit since this is Godot 3.x but most of it should be similar.

var space_state = get_world().get_direct_space_state()
var result = space_state.intersect_ray(from, to)
var world_pos = Vector3()
if result.has("position") and result.has("collider"):
    world_pos = result.get("collider").position
# do something with world_pos

tnx! im getting , error function "get_world()" not found in base self

extends Camera3D
const ray_length = 1000
@export var reticle_path: NodePath
@export var impact_normal : PackedScene
@export var force = 20.0
@export var damage = 50.0
@onready var reticle = get_node(reticle_path)

func firebullet():
	
	var screen_pos = reticle.get_global_transform_with_canvas().origin
	var camera = self
	var from = camera.project_ray_origin(screen_pos)
	var to = from + camera.project_ray_normal(screen_pos) * ray_length
	#error function "get_world()" not found in base self
	var space_state = get_world().get_direct_space_state()
	var result = space_state.intersect_ray(from, to,[self], pow(2, 1))
	#var world_pos = Vector3()
#	if result.has("position") and result.has("collider"):
#		world_pos = result.get("collider").position
#		# do something with world_pos
	if result:
		var collider = result.collider
		var n = result.normal
		var p = result.position

ok that works intersect ray seems to have been changed also, too many arguments for "intersect_ray()" call expected at most 1 but received 4

func firebullet():
	
	var screen_pos = reticle.get_global_transform_with_canvas().origin
	var camera = self
	var from = camera.project_ray_origin(screen_pos)
	var to = from + camera.project_ray_normal(screen_pos) * ray_length
	var space_state = get_world_3d().get_direct_space_state()
	#too many arguments for "intersect_ray()" call expected at most 1 but received 4
	var result = space_state.intersect_ray(from, to,[self], pow(2, 1))
	
	if result:
		var collider = result.collider
		var n = result.normal
		var p = result.position