first version of EU AI Act game
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
extends RigidBody3D
|
||||
|
||||
class_name Grabbable_Object
|
||||
|
||||
@export var grabbable: bool = true
|
||||
var is_grabbed: bool = false
|
||||
var original_parent: Node = null
|
||||
@export var grab_offset: Vector3 = Vector3(0.0, 0.0, -1.0)
|
||||
@export var drop_forward_offset: float = 1.0
|
||||
@export var weight: float = 5.0
|
||||
|
||||
@export var max_linear_speed: float = 15.0
|
||||
@export var max_angular_speed: float = 10.0
|
||||
|
||||
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
||||
# Limit linear speed
|
||||
if state.linear_velocity.length() > max_linear_speed:
|
||||
state.linear_velocity = state.linear_velocity.normalized() * max_linear_speed
|
||||
|
||||
# Limit speed of rotation (optional)
|
||||
if state.angular_velocity.length() > max_angular_speed:
|
||||
state.angular_velocity = state.angular_velocity.normalized() * max_angular_speed
|
||||
|
||||
func grab(player: Node3D):
|
||||
if not grabbable or is_grabbed or player.grabbed_item:
|
||||
return
|
||||
is_grabbed = true
|
||||
original_parent = get_parent()
|
||||
|
||||
# Disable physics
|
||||
gravity_scale = 0.0
|
||||
linear_velocity = Vector3.ZERO
|
||||
angular_velocity = Vector3.ZERO
|
||||
freeze = true
|
||||
$CollisionShape3D.disabled = true
|
||||
|
||||
# Reparent under player
|
||||
var current_transform = global_transform
|
||||
get_parent().remove_child(self)
|
||||
player.add_child(self)
|
||||
player.grabbed_item = self
|
||||
print(player.grabbed_item)
|
||||
global_transform = current_transform
|
||||
|
||||
# Move above player's head
|
||||
position = grab_offset
|
||||
rotation = Vector3(0,0,0)
|
||||
|
||||
func can_drop(player: Node3D) -> bool:
|
||||
var space_state = get_world_3d().direct_space_state
|
||||
|
||||
var start = player.global_position + Vector3(0, 2, 0)
|
||||
var forward_dir = -player.global_transform.basis.z.normalized()
|
||||
var end = start + forward_dir * drop_forward_offset
|
||||
|
||||
var query = PhysicsRayQueryParameters3D.create(start, end)
|
||||
query.exclude = [player]
|
||||
|
||||
var result = space_state.intersect_ray(query)
|
||||
|
||||
return result.is_empty()
|
||||
|
||||
func release(player: Node3D, throw := false):
|
||||
if not is_grabbed or not can_drop(player):
|
||||
return
|
||||
is_grabbed = false
|
||||
|
||||
# Re-enable physics
|
||||
$CollisionShape3D.disabled = false
|
||||
freeze = false
|
||||
gravity_scale = 1.0
|
||||
|
||||
# Reparent back to world
|
||||
var current_transform = global_transform
|
||||
get_parent().remove_child(self)
|
||||
original_parent.add_child(self)
|
||||
global_transform = current_transform
|
||||
|
||||
# Place in front of player
|
||||
var forward_dir = -player.global_transform.basis.z.normalized()
|
||||
|
||||
var player_velocity = player.velocity if player is CharacterBody3D else Vector3.ZERO
|
||||
var throw_dir = Vector3(0,2.0,0) + forward_dir + (player_velocity * 0.25)
|
||||
|
||||
global_position = player.global_position + Vector3(0, 1.5, 0) + forward_dir * drop_forward_offset
|
||||
|
||||
# Give it a small push forward (optional)
|
||||
if throw:
|
||||
apply_impulse(throw_dir * 0.01)
|
||||
else:
|
||||
apply_impulse(forward_dir * 0.001)
|
||||
player.grabbed_item = null
|
||||
|
||||
func get_weight():
|
||||
return weight
|
||||
Reference in New Issue
Block a user