class_name PlayerPickup extends Node ## 拾取组件:射线看中的 RigidBody3D 会被吸附到 InteractionPos 前。 ## 只管「拿 / 放 / 拖」,不碰移动与视角。 ## ## 接法:Player 下挂一个普通 Node,脚本挂上去;由 Player._ready() 注入射线与持握点。 ## 拖拽力度:物体被拉向持握点的速度系数 @export var pick_power: float = 10.0 var _current: RigidBody3D = null var _ray: RayCast3D var _hold_pos: Marker3D ## 由 Player 在 _ready() 注入依赖。 func setup(ray: RayCast3D, hold_pos: Marker3D) -> void: _ray = ray _hold_pos = hold_pos func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("carry"): if _current == null: _pick() else: _release() ## 每物理帧由 Player 调用一次,排在 move_and_slide() 之后。 ## 用速度把物体拽向持握点,而不是直接改 global_position —— ## 这样它仍会和场景里其他刚体正常碰撞,不会被硬塞进墙里。 func physics_step() -> void: if _current == null or _hold_pos == null: return var to_hold := _hold_pos.global_position - _current.global_position _current.set_linear_velocity(to_hold * pick_power) func _pick() -> void: if _ray == null: return var collider := _ray.get_collider() if collider is RigidBody3D: _current = collider as RigidBody3D func _release() -> void: _current = null ## 当前是否抓着东西。调试用,也方便以后加「搬运时不能开枪」这类规则。 func has_object() -> bool: return _current != null