Made the dart physics better and fixed a bug causing dart to fall when clicked
This commit is contained in:
@@ -12,7 +12,6 @@ height = 2.3862305
|
||||
[node name="RigidBody3D" type="RigidBody3D" parent="." unique_id=1993396351]
|
||||
transform = Transform3D(1, 0, 0, 0, 1.0000001, 0, 0, 0, 1.0000001, 0, 0, 0)
|
||||
center_of_mass_mode = 1
|
||||
center_of_mass = Vector3(0, 0.9, 0)
|
||||
script = ExtResource("1_s1kro")
|
||||
angle_of_plane = -25.0
|
||||
|
||||
|
||||
+79
-11
@@ -2,9 +2,11 @@ extends RigidBody3D
|
||||
|
||||
class_name Dart
|
||||
|
||||
|
||||
|
||||
#states
|
||||
var in_flight: bool = false
|
||||
var dragging: bool = false
|
||||
|
||||
#drag
|
||||
var drag_plane: Plane
|
||||
var drag_offset: Vector3 = Vector3.ZERO
|
||||
var target_pos: Vector3 = Vector3.ZERO
|
||||
@@ -12,26 +14,40 @@ 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
|
||||
const HISTORY_LENGTH = 6
|
||||
|
||||
# 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 var max_drag_speed: float = 42.0 # clamp so it doesn't go insane
|
||||
@export_range(-180,180) var angle_of_plane: float = 15.0
|
||||
@export var throw_force_multiplier: float = 0.8 # scale raw throw velocity down if it's too fast
|
||||
@export var max_throw_speed: float = 42.0 # hard cap so fast flicks don't kill the arc
|
||||
@export var flight_gravity_scale: float = 4.0 # higher = more visible arc
|
||||
@export var nose_align_speed: float = 1.0 # how fast dart rotates to face velocity
|
||||
@export var dart_forward_axis: Vector3 = Vector3.FORWARD
|
||||
|
||||
func _ready():
|
||||
freeze_mode = RigidBody3D.FREEZE_MODE_STATIC
|
||||
freeze = true
|
||||
|
||||
func start_drag(camera: Camera3D, mouse_pos: Vector2, hit_point: Vector3):
|
||||
dragging = true
|
||||
in_flight = false
|
||||
freeze = false
|
||||
|
||||
# keep it physics-active — don't freeze
|
||||
gravity_scale = 1.0 # optional: ignore gravity while held so it doesn't sag
|
||||
linear_damp = 4.0 # optional: a bit of damping for stability while dragged
|
||||
|
||||
gravity_scale = 0.0 # optional: ignore gravity while held so it doesn't sag
|
||||
linear_damp = 5.0 # optional: a bit of damping for stability while dragged
|
||||
angular_damp = 10.0
|
||||
|
||||
#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
|
||||
|
||||
|
||||
target_pos = global_position #fixes a bug where dart drops until mouse is moved.
|
||||
|
||||
position_history.clear()
|
||||
time_history.clear()
|
||||
|
||||
@@ -46,6 +62,24 @@ func update_drag(camera: Camera3D, mouse_pos: Vector2):
|
||||
if intersection:
|
||||
target_pos = intersection + drag_offset
|
||||
|
||||
func _align_dart_to_velocity(delta: float):
|
||||
if linear_velocity.length() < 0.5:
|
||||
return
|
||||
|
||||
var vel_dir = linear_velocity.normalized()
|
||||
var current_forward = global_transform.basis * dart_forward_axis
|
||||
var rotation_axis = current_forward.cross(vel_dir)
|
||||
|
||||
if rotation_axis.length() < 0.001:
|
||||
return
|
||||
|
||||
rotation_axis = rotation_axis.normalized()
|
||||
var angle = current_forward.angle_to(vel_dir)
|
||||
var rotate_amount = min(angle, nose_align_speed * delta)
|
||||
|
||||
global_transform.basis = global_transform.basis.rotated(rotation_axis, rotate_amount)
|
||||
global_transform.basis = global_transform.basis.orthonormalized()
|
||||
|
||||
func _physics_process(delta):
|
||||
if dragging:
|
||||
# chase the target position with velocity instead of teleporting
|
||||
@@ -64,18 +98,52 @@ func _physics_process(delta):
|
||||
if position_history.size() > HISTORY_LENGTH:
|
||||
position_history.pop_front()
|
||||
time_history.pop_front()
|
||||
elif in_flight:
|
||||
# Debug: confirm Y velocity is dropping (becoming negative) each frame
|
||||
print("local +X world dir: ", global_transform.basis.x)
|
||||
print("local +Y world dir: ", global_transform.basis.y)
|
||||
print("local +Z world dir: ", global_transform.basis.z)
|
||||
print("velocity dir: ", linear_velocity.normalized())
|
||||
|
||||
# Align dart nose to face velocity direction (tip points the way it's flying)
|
||||
if linear_velocity.length() > 0.5:
|
||||
_align_dart_to_velocity(delta)
|
||||
else:
|
||||
in_flight = false
|
||||
angular_velocity = Vector3.ZERO
|
||||
# If your dart tip points along +Z, use global_position + linear_velocity
|
||||
# If it points along -Z, negate the direction below
|
||||
var look_target = global_position + linear_velocity.normalized()
|
||||
var up_ref = Vector3.UP
|
||||
|
||||
# Avoid gimbal lock when flying straight up/down
|
||||
if abs(linear_velocity.normalized().dot(Vector3.UP)) > 0.99:
|
||||
up_ref = Vector3.FORWARD
|
||||
|
||||
var target_basis = Basis.looking_at(linear_velocity.normalized(), up_ref)
|
||||
global_transform.basis = global_transform.basis.slerp(
|
||||
target_basis, nose_align_speed * delta
|
||||
)
|
||||
|
||||
func release_drag():
|
||||
if not dragging:
|
||||
return
|
||||
dragging = false
|
||||
in_flight = true
|
||||
|
||||
gravity_scale = 2
|
||||
linear_damp = 1.0 # reset to whatever your normal dart damping is
|
||||
gravity_scale = flight_gravity_scale
|
||||
angular_damp = 0.0
|
||||
linear_damp = 0.0 # reset to whatever your normal dart damping is
|
||||
|
||||
var velocity = calculate_throw_velocity() * 1.0
|
||||
var velocity = calculate_throw_velocity() * throw_force_multiplier
|
||||
if velocity.length() > max_throw_speed:
|
||||
velocity = velocity.normalized() * max_throw_speed
|
||||
linear_velocity = velocity
|
||||
# angular_velocity left as-is from physics, or compute your own spin here
|
||||
|
||||
print("throw speed: %.2f" % velocity.length())
|
||||
print("gravity_scale: ", gravity_scale)
|
||||
print("linear_damp: ", linear_damp)
|
||||
|
||||
func calculate_throw_velocity() -> Vector3:
|
||||
if position_history.size() < 2:
|
||||
|
||||
@@ -29,6 +29,7 @@ transform = Transform3D(1, 0, 0, 0, 0.8363807, -0.5481493, 0, 0.5481492, 0.83638
|
||||
transform = Transform3D(-0.789482, 0.24223976, -0.56394875, -0.56595325, 0.06825608, 0.821607, 0.23751883, 0.9678125, 0.083209395, -46.816067, 15.942318, -50.370865)
|
||||
|
||||
[node name="StaticBody3D" type="StaticBody3D" parent="." unique_id=889230389]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 63.39778)
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" unique_id=229129629]
|
||||
transform = Transform3D(100, 0, 0, 0, 100, 0, 0, 0, 100, 0, 0, 0)
|
||||
|
||||
Reference in New Issue
Block a user