Added Dart Physics
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
extends RigidBody3D
|
||||
|
||||
class_name Dart
|
||||
|
||||
|
||||
|
||||
var dragging: bool = false
|
||||
var drag_plane: Plane
|
||||
var drag_offset: Vector3 = Vector3.ZERO
|
||||
var target_pos: Vector3 = Vector3.ZERO
|
||||
|
||||
# velocity tracking for release throw
|
||||
var position_history: Array[Vector3] = []
|
||||
var time_history: Array[float] = []
|
||||
const HISTORY_LENGTH = 5
|
||||
|
||||
# drag "stiffness" tuning
|
||||
@export var drag_follow_speed: float = 20.0 # how fast it chases the mouse
|
||||
@export var max_drag_speed: float = 15.0 # clamp so it doesn't go insane
|
||||
@export_range(-180,180) var angle_of_plane: float = 15.0
|
||||
|
||||
func start_drag(camera: Camera3D, mouse_pos: Vector2, hit_point: Vector3):
|
||||
dragging = true
|
||||
|
||||
# keep it physics-active — don't freeze
|
||||
gravity_scale = 0.0 # optional: ignore gravity while held so it doesn't sag
|
||||
linear_damp = 4.0 # optional: a bit of damping for stability while dragged
|
||||
|
||||
#drag_plane = Plane(camera.global_transform.basis.z, hit_point)
|
||||
var base_normal = camera.global_transform.basis.z
|
||||
var tilt = base_normal.rotated(camera.global_transform.basis.x, deg_to_rad(angle_of_plane)) # tilt adjustable around camera's right axis
|
||||
drag_plane = Plane(tilt.normalized(), hit_point)
|
||||
drag_offset = global_position - hit_point
|
||||
|
||||
position_history.clear()
|
||||
time_history.clear()
|
||||
|
||||
func update_drag(camera: Camera3D, mouse_pos: Vector2):
|
||||
if not dragging:
|
||||
return
|
||||
|
||||
var ray_origin = camera.project_ray_origin(mouse_pos)
|
||||
var ray_dir = camera.project_ray_normal(mouse_pos)
|
||||
|
||||
var intersection = drag_plane.intersects_ray(ray_origin, ray_dir)
|
||||
if intersection:
|
||||
target_pos = intersection + drag_offset
|
||||
|
||||
func _physics_process(delta):
|
||||
if dragging:
|
||||
# chase the target position with velocity instead of teleporting
|
||||
var to_target = target_pos - global_position
|
||||
var desired_velocity = to_target * drag_follow_speed
|
||||
|
||||
if desired_velocity.length() > max_drag_speed:
|
||||
desired_velocity = desired_velocity.normalized() * max_drag_speed
|
||||
|
||||
linear_velocity = desired_velocity
|
||||
angular_velocity = angular_velocity.lerp(Vector3.ZERO, 0.2) # optional: damp spin while dragging
|
||||
|
||||
# track actual position for momentum calc on release
|
||||
position_history.append(global_position)
|
||||
time_history.append(Time.get_ticks_msec() / 1000.0)
|
||||
if position_history.size() > HISTORY_LENGTH:
|
||||
position_history.pop_front()
|
||||
time_history.pop_front()
|
||||
|
||||
func release_drag():
|
||||
if not dragging:
|
||||
return
|
||||
dragging = false
|
||||
|
||||
gravity_scale = 1.0
|
||||
linear_damp = 0.0 # reset to whatever your normal dart damping is
|
||||
|
||||
var velocity = calculate_throw_velocity()
|
||||
linear_velocity = velocity
|
||||
# angular_velocity left as-is from physics, or compute your own spin here
|
||||
|
||||
func calculate_throw_velocity() -> Vector3:
|
||||
if position_history.size() < 2:
|
||||
return linear_velocity # fallback to whatever physics already had
|
||||
|
||||
var start_pos = position_history[0]
|
||||
var end_pos = position_history[position_history.size() - 1]
|
||||
var start_time = time_history[0]
|
||||
var end_time = time_history[time_history.size() - 1]
|
||||
|
||||
var dt = end_time - start_time
|
||||
if dt <= 0.0:
|
||||
return linear_velocity
|
||||
|
||||
return (end_pos - start_pos) / dt
|
||||
Reference in New Issue
Block a user