- палитра целиком (индиго, пурпур, ледяная бирюза): SOLID/NEON, SURFACES/GLOWS, туман, ambient, свет запекания, ворота, полосы, надписи; новое небо - запекание 384 сэмпла + огни у подножия башни - вентилятор: VENT_MAX_RISE 16, VENT_ACCEL 80; шахта-лифт без знака и без столба/света (hidden) - музыка Race 2: Poloz «On My Way to Hell» с 1:40 Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
58 lines
2.3 KiB
GDScript
58 lines
2.3 KiB
GDScript
extends Area3D
|
|
# Ускоряющая полоса: на ней игрок, бегущий вдоль неё, быстро добирает скорость (до speed, но не выше MAX_SPEED игрока).
|
|
# Направление — локальная ось -Z узла (rotation.y = рыскание, как у ворот гонки). Эффект локальный, в сеть не уходит.
|
|
# Начало координат — центр полосы на полу. Рисуется кодом: бирюзовые стрелки, бегущие по ходу.
|
|
|
|
@export var size := Vector2(6.0, 10.0) # ширина (X) и длина (Z), м
|
|
@export var speed := 22.0
|
|
@export var color := Color(0.85, 0.45, 1.0) # пурпурно-белый: отличается от ледяных стрелок-подсказок трассы
|
|
|
|
const SHADER := """
|
|
shader_type spatial;
|
|
render_mode unshaded, blend_add, cull_disabled, depth_draw_never;
|
|
uniform vec4 tint : source_color = vec4(0.85, 0.45, 1.0, 1.0);
|
|
uniform vec2 dims = vec2(6.0, 10.0);
|
|
varying vec2 uv;
|
|
void vertex() { uv = VERTEX.xz; }
|
|
void fragment() {
|
|
// uv.y < 0 — вперёд (-Z); шевроны бегут вперёд
|
|
float across = abs(uv.x) / (dims.x * 0.5);
|
|
float t = -uv.y * 0.35 - TIME * 2.6 + across * 0.9;
|
|
float chev = smoothstep(0.55, 0.62, fract(t)) * (1.0 - smoothstep(0.78, 0.9, fract(t)));
|
|
float edge = smoothstep(0.86, 0.94, across);
|
|
float end = smoothstep(0.0, 0.1, 0.5 - abs(uv.y) / dims.y);
|
|
ALBEDO = tint.rgb;
|
|
ALPHA = clamp((chev * 0.85 + edge * 0.7 + 0.1) * end, 0.0, 1.0);
|
|
}
|
|
"""
|
|
|
|
func _ready() -> void:
|
|
collision_layer = 0
|
|
collision_mask = 1
|
|
var cs := CollisionShape3D.new()
|
|
var shape := BoxShape3D.new()
|
|
shape.size = Vector3(size.x, 2.4, size.y)
|
|
cs.shape = shape
|
|
cs.position.y = 1.2
|
|
add_child(cs)
|
|
var sh := Shader.new()
|
|
sh.code = SHADER
|
|
var sm := ShaderMaterial.new()
|
|
sm.shader = sh
|
|
sm.set_shader_parameter("tint", color)
|
|
sm.set_shader_parameter("dims", size)
|
|
var pm := PlaneMesh.new()
|
|
pm.size = size
|
|
var mi := MeshInstance3D.new()
|
|
mi.mesh = pm
|
|
mi.material_override = sm
|
|
mi.position.y = 0.07
|
|
mi.cast_shadow = GeometryInstance3D.SHADOW_CASTING_SETTING_OFF
|
|
add_child(mi)
|
|
|
|
func _physics_process(_delta: float) -> void:
|
|
var dir := -global_transform.basis.z
|
|
for b in get_overlapping_bodies():
|
|
if b.has_method("apply_boost"):
|
|
b.apply_boost(dir, speed)
|