Files
godot-demo-projects/3d/physics_tests/utils/rigidbody_pick.gd
2025-10-11 05:03:59 -07:00

56 lines
1.7 KiB
GDScript

extends RigidBody3D
const MOUSE_DELTA_COEFFICIENT: float = 0.01
const CAMERA_DISTANCE_COEFFICIENT: float = 0.2
var _picked: bool = false
var _last_mouse_pos := Vector2.ZERO
var _mouse_pos := Vector2.ZERO
func _ready() -> void:
input_ray_pickable = true
func _input(any_input_event: InputEvent) -> void:
if any_input_event is InputEventMouseButton:
if not any_input_event.pressed and any_input_event.button_index == MOUSE_BUTTON_LEFT:
_picked = false
if any_input_event is InputEventMouseMotion:
_mouse_pos = any_input_event.position
func _input_event(_camera: Camera3D, any_input_event: InputEvent, _position: Vector3, _normal: Vector3, _shape_idx: int) -> void:
if any_input_event is InputEventMouseButton:
if any_input_event.pressed and any_input_event.button_index == MOUSE_BUTTON_LEFT:
_picked = true
_mouse_pos = any_input_event.position
_last_mouse_pos = _mouse_pos
func _physics_process(delta: float) -> void:
if _picked:
var mouse_delta := _mouse_pos - _last_mouse_pos
var world_delta := Vector3.ZERO
world_delta.x = mouse_delta.x * MOUSE_DELTA_COEFFICIENT
world_delta.y = -mouse_delta.y * MOUSE_DELTA_COEFFICIENT
var camera := get_viewport().get_camera_3d()
if camera:
var camera_basis := camera.global_transform.basis
world_delta = camera_basis * world_delta
var camera_dist := camera.global_transform.origin.distance_to(global_transform.origin)
const DEFAULT_CAMERA_FOV = 75.0
var fov_coefficient := camera.fov / DEFAULT_CAMERA_FOV
world_delta *= CAMERA_DISTANCE_COEFFICIENT * camera_dist * fov_coefficient
if freeze:
global_transform.origin += world_delta
else:
linear_velocity = world_delta / delta
_last_mouse_pos = _mouse_pos