Thanks for replying, I made a work around by adding Area 3d to the rigid body to detect the Area 3D instead of the other way around, no lag.
But I also made a minimal reproducible example for anyone interested in identifying the issue. You can download it here.
Here is a video demonstration.
Scene set ups.
Main Scene has 4 detection areas, 4 objects to be dragged around, floor, camera, light, and a static body 3D to keep the object on the same height as detection areas when dragging.
Detection Scene is a Area 3D with mesh as visual indicator and a 5x1x7 collision shape 3D. Collision mask set to 3.
3D Obejct is a Rigid Body 3D with 2x2x2 collision shape and mesh. Collision layer set to 1 (to collide with ground), 2(collide with ray), 3(collide with detection area)
Scripts
3D object
Stores a 3d coordinate that the object will return to
Check to see if the object is inside of a detection area
extends RigidBody3D
class_name Collider
var detected: bool = false
var memorized_position: Vector3 = Vector3.ZERO
func _ready():
memorized_position = global_transform.origin
Detection Area
Check if the body entered is desired object
Set the condition accordingly and print to check for the correct interaction
extends Area3D
func _on_body_entered(body):
if body is Collider:
body.detected = true
print(body.name, " entered: ", self.name)
func _on_body_exited(body):
if body is Collider:
body.detected = false
print(body.name, " Left: ", self.name)
Script for main scene
Camera reference and variables
@onready var camera_3d = $Camera3D
var selected_object : Node3D = null
var is_dragging : bool = false
var offset : Vector3 = Vector3.ZERO
Input function
func _input(event):
# Clicking on 3D object
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
if event.pressed:
# Selecting the object
var mouse_pos = event.position
var ray_origin = camera_3d.project_ray_origin(mouse_pos)
var ray_direction = camera_3d.project_ray_normal(mouse_pos)
# Create the PhysicsRayQueryParameters3D
var ray = PhysicsRayQueryParameters3D.new()
ray.from = ray_origin
ray.to = ray_origin + ray_direction * 1000
ray.collide_with_bodies = true
ray.collide_with_areas = false
ray.collision_mask = 2
var space_state = get_world_3d().direct_space_state
# Perform the raycast
var result = space_state.intersect_ray(ray)
if result:
var collider = result.collider
if collider:
selected_object = collider
# Adjust the offset to account for the die's floating position
var ground_position = result.position
offset = selected_object.global_transform.origin - ground_position
is_dragging = true
else:
#Releasing the object
if selected_object:
var tween = selected_object.create_tween()
tween.tween_property(selected_object, "position", selected_object.memorized_position, 0.5)
#delete dragged die
if selected_object.detected:
selected_object.queue_free()
selected_object = null
is_dragging = false
# Dragging the selected object
if event is InputEventMouseMotion and is_dragging and selected_object:
var mouse_pos = event.position
var ray_origin = camera_3d.project_ray_origin(mouse_pos)
var ray_direction = camera_3d.project_ray_normal(mouse_pos)
# Recalculate ray
var ray = PhysicsRayQueryParameters3D.new()
ray.from = ray_origin
ray.to = ray_origin + ray_direction * 1000
var space_state = get_world_3d().direct_space_state
var result = space_state.intersect_ray(ray)
if result:
var new_position = result.position + offset
selected_object.global_transform.origin = new_position
var tween = selected_object.create_tween()
#selected_object.global_transform.origin = start_position + position_offset ##Line up instantly
tween.tween_property(selected_object, "position", new_position, 0.05)
I feel like it has something to do with the way tween moves the object, but I couldn’t test it because I wasn’t able to figure out how to move it in a similar fashion by applying force.