extends Node3D @export_node_path(Camera3D) var camera_path var domino: PackedScene var ghost_domino: Node3D var camera: Camera3D var tool_active: bool = true func _ready(): domino = preload("res://Domino.tscn") ghost_domino = preload("res://GhostDomino.tscn").instantiate() camera = get_node(camera_path) func _is_active(): return tool_active and !Input.is_action_pressed("cam_adjust") func _physics_process(delta): if ghost_domino.get_parent(): remove_child(ghost_domino) if not _is_active(): return var space_state = get_world_3d().direct_space_state if space_state == null: return var mouse_position = get_viewport().get_mouse_position() var mouse_3d_origin = camera.project_ray_origin(mouse_position) var mouse_3d_normal = camera.project_ray_normal(mouse_position) var query = PhysicsRayQueryParameters3D.new() query.from = camera.position query.to = mouse_3d_origin + mouse_3d_normal * 64 var raytrace_results = space_state.intersect_ray(query) if raytrace_results.has("position"): ghost_domino.position = raytrace_results.position + Vector3.UP * 0.5 if not ghost_domino.get_parent(): add_child(ghost_domino) func _input(event): if not _is_active(): return if event.is_action_pressed("use_tool") and ghost_domino.get_parent(): var new_domino: RigidDynamicBody3D = domino.instantiate() new_domino.transform = ghost_domino.transform add_child(new_domino) if event.is_action_pressed("domino_rotate_clockwise"): ghost_domino.rotate_y(-PI / 12) if event.is_action_pressed("domino_rotate_anticlockwise"): ghost_domino.rotate_y(PI / 12)