Preliminary lasers

This commit is contained in:
Marco 2025-10-09 09:11:25 +02:00
commit 7cb5bfb593
20 changed files with 1779 additions and 1049 deletions

83
addons/laser/laser.gd Normal file
View file

@ -0,0 +1,83 @@
extends Node3D
@onready var laserRay = $Laser
@onready var beamSegment = load("res://addons/laser/laser_beam.tscn")
@onready var laser = load("res://addons/laser/laser.tscn")
const laserLength = 100
const laserDensity = 1.5
const reflectLayer = 2
var points = []
var splits = []
var truePos = null
var trueRot = null
signal openDoor(door)
#since raycast moves all around, this funciton returns it to the starting location
#starting location and rotation should be changed to change the permanent place of the laser
#do not try to change the rotation or position of the parent Node3D to change the starting point
#and trajectory of the laser. Please use truePos and trueRot
func positions():
laserRay.global_position = truePos
laserRay.target_position = trueRot
func _ready():
laserRay.target_position = laserRay.target_position*laserLength
truePos = laserRay.global_position
trueRot = laserRay.target_position*laserLength
var reflectTarget = null
func _process(delta):
points = [laserRay.global_position] #cleans the list of places the laser goes
while true:
laserRay.force_raycast_update()
if laserRay.is_colliding(): #check if laser in current trajectory is colliding with anything
if laserRay.get_collider().collision_layer == reflectLayer: #checks if object is reflective
reflect()
else:
points.append(laserRay.get_collision_point())
updateLaserBeam()
positions()
break
else: #if not colliding, it is assumed that it will go on to infinity and beyond.
if reflectTarget != null:
if points[-1] != laserRay.global_position + (reflectTarget*laserLength):
points.append(laserRay.global_position + (reflectTarget*laserLength))
else:
if points[-1] != laserRay.global_position + (laserRay.target_position*laserLength):
points.append(laserRay.global_position + (laserRay.target_position*laserLength))
updateLaserBeam()
positions()
break
func updateLaserBeam(): #connects the points with spheres
for i in range(0, $Beams.get_child_count()):
$Beams.get_child(i).queue_free()
for i in range(0, len(points)-1):
var line = points[i+1] - points[i]
var direction = (line.normalized())/laserDensity
var pos = points[i]
for j in range(0, (line/direction).x):
var instance = beamSegment.instantiate()
$Beams.add_child(instance)
$Beams.get_child(-1).global_position = pos
pos = pos + direction
func reflect():
reflectTarget = ((laserRay.get_collision_point() - laserRay.global_position)).bounce(laserRay.get_collision_normal())
laserRay.global_position = laserRay.get_collision_point()
laserRay.target_position = reflectTarget*laserLength
points.append(laserRay.global_position)
updateLaserBeam()
#this whole sequence goes like this: laser hits reflective object, move start of
#laser to the hit point, logs the laser's current position, aims the laser the way
#it should based on the bounce function, sees if it hits any reflective surface,
#and repeat

View file

@ -0,0 +1 @@
uid://cuwmjh8siacg1

14
addons/laser/laser.tscn Normal file
View file

@ -0,0 +1,14 @@
[gd_scene load_steps=2 format=3 uid="uid://cdxjy1yy8tqeu"]
[ext_resource type="Script" uid="uid://cuwmjh8siacg1" path="res://addons/laser/laser.gd" id="1_xyxma"]
[node name="Node3D" type="Node3D"]
script = ExtResource("1_xyxma")
[node name="Laser" type="RayCast3D" parent="."]
target_position = Vector3(1, 1, 2.08165e-12)
collision_mask = 7
[node name="Beams" type="Node3D" parent="."]
[node name="Splits" type="Node3D" parent="."]

View file

@ -0,0 +1,14 @@
[gd_scene load_steps=3 format=3 uid="uid://wfbn16mxdrtl"]
[sub_resource type="SphereMesh" id="SphereMesh_nag17"]
radius = 0.1
height = 0.2
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_jodxn"]
albedo_color = Color(1, 0, 0, 1)
emission_enabled = true
emission = Color(1, 0, 0, 1)
[node name="laserBeam" type="MeshInstance3D"]
mesh = SubResource("SphereMesh_nag17")
surface_material_override/0 = SubResource("StandardMaterial3D_jodxn")