I have a cube that follows my mouse cursor but for some reason it flickers and disappears every now and then on the screen (see recording)

extends Node3D
var mouse: Vector2

# Called when the node enters the scene tree for the first time.
func _ready():
	pass # Replace with function body.


# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
	pass
	
func _input(event):
#	if event is InputEventMouse:
#		mouse = event.position
#	if event is InputEventMouseButton and event.is_pressed():
#		if event.button_index == MOUSE_BUTTON_LEFT:
#			get_selection()
	
	if event is InputEventMouseMotion:
		mouse = event.position
		get_selection()
			
func get_selection():
	#Boiler plate code to figure out where the cursor is pointing at
	var worldspace= get_world_3d().direct_space_state
	var camera = $Camera3D
	var start = camera.project_ray_origin(mouse)
	var end = start + camera.project_ray_normal(mouse) * 1000
	var query = PhysicsRayQueryParameters3D.create(start, end)
	query.exclude = [$StaticBody3D2]
	query.collide_with_areas = true
	var result = worldspace.intersect_ray(query)
	
#	print(result)
	if(result):		
		var pos = Vector3(result.position)
		
		#snapper is the size of the my grid that I want the cube to snap to
		var snapper = Vector3(1,1,1)
		# https://docs.godotengine.org/en/stable/classes/class_%40globalscope.html#class-globalscope-method-snapped
		# https://docs.godotengine.org/en/stable/classes/class_vector3.html#class-vector3-method-snapped
		var snappedPos = pos.snapped(snapper)
#		print(snappedPos)
		var cube = $StaticBody3D2
		
		if(cube.global_position != snappedPos):
			cube.global_position = snappedPos

Any ideas what that might be?

Max

EDIT: as per @award comment, I have removed the ZIP file and replaced it with a YT video instead

  • Tomcat replied to this.
  • max_godot
    Instead of

    var snappedPos = pos.snapped(snapper)

    try:

    pos.y += .001
    var snappedPos = pos.snapped(snapper)

    Or set the y position to ground height manually after snapping (which is less hacky than the above solution)

    Hide the ground plane to se what's happening. It's a floating point rounding/precision error and your code has more lines that can cause trouble because of this, like using == and != operators with vectors (whose components are floats).

    That is very weird. I copy pasted your script and it worked perfectly for me. Here was my setup:

    Btw thank you for providing all the necessary code. In the future, please consider finding a better way to distribute your screen recording. I know you're fine, but zip files aren't always trustworthy... Try youtube or pasting a gif.

      max_godot Any ideas what that might be?

      Can you post the entire scene? I have a suspicion that the cube is trying to "fail".

        max_godot
        Instead of

        var snappedPos = pos.snapped(snapper)

        try:

        pos.y += .001
        var snappedPos = pos.snapped(snapper)

        Or set the y position to ground height manually after snapping (which is less hacky than the above solution)

        Hide the ground plane to se what's happening. It's a floating point rounding/precision error and your code has more lines that can cause trouble because of this, like using == and != operators with vectors (whose components are floats).

          xyz Thanks, that fixed it! 🙂 What would you recommend as comparison operator instead for the floating point vectors?

          • xyz replied to this.

            award Already working on getting an account at a peertube instance 🙂

            max_godot What would you recommend as comparison operator instead for the floating point vectors

            Vector3::is_equal_approx(). There is equivalent for Vector2 as well as plain floats.

            max_godot Ah, @xyz already answered that.

            Well, yeah. The cube sort of tries to fall "under the floor". If you move the mouse slowly, at times it disappears completely.

            If you substitute

            40		var snapper = Vector3(1.0, 0.999, 1.0)

            the second argument different from 0, the "flickering" (dips) should stop. But I'm not sure that this is a good solution. The @xyz solution is certainly better.

              Tomcat The problem is in precision of ray hit results. If the ground plane is at y=0, due to float imprecision the returned hitpoint's y may fluctuate in a small range around 0.0, sometimes going above and sometimes below 0.0. When it goes below the snapping will snap it to -1 instead of 0.

              Since in this case everything happens on the ground plane, the "cleanest" solution is not to snap on y axis at all. Set the y value manually.