手掌指针
This commit is contained in:
Binary file not shown.
|
After Width: | Height: | Size: 321 B |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c67qe66m2aft4"
|
||||
path="res://.godot/imported/grab.png-15ccc11b1ce7bc67c3d60db6d0ffc1ed.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://character/assets/grab.png"
|
||||
dest_files=["res://.godot/imported/grab.png-15ccc11b1ce7bc67c3d60db6d0ffc1ed.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 341 B |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bkq6ya350cae8"
|
||||
path="res://.godot/imported/grab_hover.png-ae4fc79bd64160559a632cc7a661f9e3.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://character/assets/grab_hover.png"
|
||||
dest_files=["res://.godot/imported/grab_hover.png-ae4fc79bd64160559a632cc7a661f9e3.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
@@ -5,13 +5,15 @@ extends CharacterBody3D
|
||||
## Look 视角 character/player/player_look.gd
|
||||
## Motor 移动跳跃 character/player/player_motor.gd
|
||||
## Pickup 拾取 character/player/player_pickup.gd
|
||||
## Animator 动画表现 character/player/player_animator.gd(挂在 Body/AnimationPlayer 上)
|
||||
## Animator 动画表现 character/player/player_animator.gd(挂在 AnimationPlayer 上)
|
||||
##
|
||||
## 本脚本不实现任何操作,只负责「谁先谁后」和「谁有权跑」。
|
||||
|
||||
@onready var body: Node3D = $Body
|
||||
@onready var camera_rig: Node3D = $CameraRig
|
||||
@onready var camera: Camera3D = $CameraRig/Camera
|
||||
## 准心(挂在 CameraRig/HUD 下)。远端玩家的 HUD 会随 camera_rig 一起被释放。
|
||||
@onready var crosshair: Crosshair = $CameraRig/HUD/Crosshair
|
||||
@onready var animation_player: PlayerAnimator = $AnimationPlayer
|
||||
@onready var look: PlayerLook = $Look
|
||||
@onready var motor: PlayerMotor = $Motor
|
||||
@@ -43,6 +45,8 @@ func _ready() -> void:
|
||||
camera.get_node("InteractionRay") as RayCast3D,
|
||||
camera.get_node("InteractionPos") as Marker3D
|
||||
)
|
||||
# 准心接线:拾取组件一发现交互状态变化,就通知准心换外观(点 / 手 / 抓)。
|
||||
pickup.interact_state_changed.connect(_on_pickup_interact_state_changed)
|
||||
set_mouse_captured(true)
|
||||
|
||||
|
||||
@@ -62,6 +66,17 @@ func set_mouse_captured(captured: bool) -> void:
|
||||
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED if captured else Input.MOUSE_MODE_VISIBLE
|
||||
|
||||
|
||||
## 把拾取组件的两个布尔量收敛成准心的三态。优先级:抓着 > 指着 > 没有。
|
||||
## 系统鼠标指针由准心自己同步(Crosshair.sync_os_cursor),这里不用管。
|
||||
func _on_pickup_interact_state_changed(hovering: bool, holding: bool) -> void:
|
||||
var state := Crosshair.GrabState.NONE
|
||||
if holding:
|
||||
state = Crosshair.GrabState.HOLDING
|
||||
elif hovering:
|
||||
state = Crosshair.GrabState.HOVER
|
||||
crosshair.set_grab_state(state)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
# 顺序固定:算速度 → 推进 → 播动画 → 搬物体。
|
||||
# 由根节点统一编排,各组件自己不许写 _physics_process ——
|
||||
|
||||
@@ -12,9 +12,17 @@ extends Node
|
||||
## 投掷初速度(米/秒):按 Q 甩出去时给物体的速度大小。
|
||||
@export var throw_speed: float = 12.0
|
||||
|
||||
## 交互状态变化时发出。
|
||||
## hovering = 准心正指着可拖拽的刚体(还没抓);holding = 正抓着东西。
|
||||
## Player 接住这个信号去切准心外观。只在两者之一变化时发,避免每帧刷 UI。
|
||||
signal interact_state_changed(hovering: bool, holding: bool)
|
||||
|
||||
var _current: RigidBody3D = null
|
||||
var _ray: RayCast3D
|
||||
var _hold_pos: Marker3D
|
||||
## 上一次发出的状态,用来只在「变化那一刻」发信号。
|
||||
var _hovering: bool = false
|
||||
var _holding: bool = false
|
||||
|
||||
|
||||
## 由 Player 在 _ready() 注入依赖。
|
||||
@@ -42,6 +50,7 @@ func _unhandled_input(event: InputEvent) -> void:
|
||||
## 用速度把物体拽向持握点,而不是直接改 global_position ——
|
||||
## 这样它仍会和场景里其他刚体正常碰撞,不会被硬塞进墙里。
|
||||
func physics_step() -> void:
|
||||
_update_interact_state()
|
||||
# 用 is_instance_valid 而不是 `== null`:物体可能在拖拽途中被 destroy,
|
||||
# 那种情况下引用不是 null 而是「已被释放」,直接取 global_position 会报错。
|
||||
if not is_instance_valid(_current) or not is_instance_valid(_hold_pos):
|
||||
@@ -50,6 +59,23 @@ func physics_step() -> void:
|
||||
_current.set_linear_velocity(to_hold * pick_power)
|
||||
|
||||
|
||||
## 检测「指着可拖拽物 / 正抓着东西」这两个状态,**只在变化时**发信号。
|
||||
## 每帧都发会让 UI 无谓重绘,所以这里自己记着上一次的结果。
|
||||
func _update_interact_state() -> void:
|
||||
if _ray == null:
|
||||
return
|
||||
# 主动刷新一次:RayCast3D 的结果通常滞后于本帧的 move_and_slide,
|
||||
# 不强制更新的话,跑动中瞄到物体要慢一帧才亮。
|
||||
_ray.force_raycast_update()
|
||||
var hovering := _ray.get_collider() is RigidBody3D
|
||||
var holding := is_instance_valid(_current)
|
||||
if hovering == _hovering and holding == _holding:
|
||||
return
|
||||
_hovering = hovering
|
||||
_holding = holding
|
||||
interact_state_changed.emit(_hovering, _holding)
|
||||
|
||||
|
||||
func _grab() -> void:
|
||||
if _ray == null:
|
||||
return
|
||||
|
||||
Reference in New Issue
Block a user