47 lines
1.2 KiB
GDScript3
47 lines
1.2 KiB
GDScript3
|
|
extends CanvasLayer
|
||
|
|
|
||
|
|
@export var target: Node2D
|
||
|
|
@onready var rect = $ColorRect
|
||
|
|
|
||
|
|
var mat: ShaderMaterial
|
||
|
|
var last_pos: Vector2
|
||
|
|
|
||
|
|
func _ready():
|
||
|
|
mat = rect.material as ShaderMaterial
|
||
|
|
if target != null:
|
||
|
|
last_pos = target.global_position
|
||
|
|
|
||
|
|
func _process(delta: float) -> void:
|
||
|
|
if target == null:
|
||
|
|
return
|
||
|
|
|
||
|
|
if mat == null:
|
||
|
|
return
|
||
|
|
|
||
|
|
var vp_size: Vector2 = get_viewport().get_visible_rect().size
|
||
|
|
|
||
|
|
# 玩家世界坐标
|
||
|
|
var world_pos: Vector2 = target.global_position
|
||
|
|
|
||
|
|
# ✅ 世界 -> 屏幕像素坐标(包含相机影响)
|
||
|
|
var screen_pos: Vector2 = get_viewport().get_canvas_transform() * world_pos
|
||
|
|
|
||
|
|
# 速度方向(世界空间)
|
||
|
|
var vel: Vector2 = (world_pos - last_pos) / max(delta, 0.0001)
|
||
|
|
last_pos = world_pos
|
||
|
|
|
||
|
|
var speed: float = vel.length()
|
||
|
|
var dir: Vector2 = Vector2.RIGHT
|
||
|
|
if speed > 0.001:
|
||
|
|
dir = vel / speed
|
||
|
|
|
||
|
|
# ✅ 船头前移(拨水发生在玩家前面)
|
||
|
|
var front_offset_px: Vector2 = dir * 30.0
|
||
|
|
var uv_front: Vector2 = (screen_pos + front_offset_px) / vp_size
|
||
|
|
uv_front = uv_front.clamp(Vector2(0, 0), Vector2(1, 1))
|
||
|
|
|
||
|
|
|
||
|
|
mat.set_shader_parameter("obj_uv", uv_front)
|
||
|
|
mat.set_shader_parameter("obj_dir", dir)
|
||
|
|
mat.set_shader_parameter("obj_speed", clamp(speed / 600.0, 0.0, 2.0))
|