Files
Blockline/scripts/stair_guard.gd
T

49 lines
1.8 KiB
GDScript
Raw Normal View History

2026-09-12 11:01:37 +02:00
class_name StairGuard
extends RefCounted
# One continuous sloping prism replaces the stepped collision faces of a guard.
static func build(parent: Node3D, x: float, first_z: float, direction: float, bottom: float, rise: float, batch: UrbanMeshBatch = null) -> void:
var body := parent as StaticBody3D
if body == null: body = StaticBody3D.new()
if body != parent: body.name = "SmoothStairGuard"
body.collision_layer = 1
body.collision_mask = 0
var points := PackedVector3Array()
for end in [0.0, 1.0]:
var z: float = first_z + direction * (-0.2 + end * 7.6)
var y: float = bottom + rise / 38.0 + end * rise
for side in [-0.06, 0.06]:
for height in [0.0, 0.96]: points.append(Vector3(x + side, y + height, z))
var shape := ConvexPolygonShape3D.new()
shape.points = points
var collider := CollisionShape3D.new()
collider.shape = shape
body.add_child(collider)
if body != parent: parent.add_child(body)
if batch:
batch.mesh(surface(points), Vector3.ZERO, "metal", Color("343b3d"))
static func surface(points: PackedVector3Array) -> ArrayMesh:
# Use the collision prism's exact corners: the visible top is equally smooth.
var tool := SurfaceTool.new()
tool.begin(Mesh.PRIMITIVE_TRIANGLES)
var center := Vector3.ZERO
for point in points: center += point / 8.0
for face in [[0,2,3,1], [4,5,7,6], [0,1,5,4], [2,6,7,3], [1,3,7,5], [0,4,6,2]]:
for triangle in [[face[0],face[1],face[2]], [face[0],face[2],face[3]]]:
var a: Vector3 = points[triangle[0]]
var b: Vector3 = points[triangle[1]]
var c: Vector3 = points[triangle[2]]
var normal := (c-a).cross(b-a).normalized()
if normal.dot((a+b+c)/3.0-center) < 0:
var swap := b
b = c
c = swap
normal = -normal
for vertex in [a,b,c]:
tool.set_normal(normal)
tool.set_uv(Vector2(vertex.z,vertex.y))
tool.add_vertex(vertex)
return tool.commit()