69 lines
2.0 KiB
GDScript
69 lines
2.0 KiB
GDScript
extends RigidBody3D
|
|
|
|
@export var speed: float = 10.0
|
|
@export var muzzle_prefab: PackedScene
|
|
@export var impact_prefab: PackedScene
|
|
@export var delay_trails_start: float = 0.1
|
|
@export var trails: Array[GPUTrail3D]
|
|
|
|
var direction: Vector3 = Vector3.FORWARD
|
|
var fire_point_position: Vector3
|
|
|
|
func set_fire_point(fp_position: Vector3):
|
|
fire_point_position = fp_position
|
|
|
|
func _ready():
|
|
delay_trails()
|
|
spawn_muzzle()
|
|
contact_monitor = true
|
|
max_contacts_reported = 1
|
|
|
|
func _integrate_forces(state):
|
|
linear_velocity = direction * speed
|
|
|
|
var collision = state.get_contact_count()
|
|
if collision > 0:
|
|
var contact = state.get_contact_collider_position(0)
|
|
var normal = state.get_contact_local_normal(0)
|
|
spawn_impact(contact, normal)
|
|
queue_free()
|
|
|
|
func spawn_muzzle():
|
|
if muzzle_prefab:
|
|
var muzzle_instance = muzzle_prefab.instantiate()
|
|
call_deferred("add_child", muzzle_instance)
|
|
await get_tree().create_timer(0.001).timeout
|
|
muzzle_instance.global_transform.origin = fire_point_position
|
|
muzzle_instance.play_particles = true
|
|
|
|
await get_tree().create_timer(3.0).timeout
|
|
if is_instance_valid(muzzle_instance):
|
|
muzzle_instance.queue_free()
|
|
|
|
func spawn_impact(contact_point: Vector3 = Vector3.ZERO, contact_normal: Vector3 = Vector3.ZERO):
|
|
if impact_prefab:
|
|
var impact_instance = impact_prefab.instantiate()
|
|
get_tree().current_scene.add_child(impact_instance)
|
|
impact_instance.play_particles = true
|
|
|
|
impact_instance.global_transform.origin = contact_point
|
|
impact_instance.look_at(contact_point + contact_normal, Vector3.UP)
|
|
|
|
await get_tree().create_timer(3.0).timeout
|
|
if is_instance_valid(impact_instance):
|
|
impact_instance.queue_free()
|
|
|
|
func delay_trails():
|
|
if trails.is_empty():
|
|
return
|
|
|
|
for trail in trails:
|
|
if is_instance_valid(trail):
|
|
trail.speed_scale = 0 # Stop movement initially, avoids glitches
|
|
|
|
await get_tree().create_timer(delay_trails_start).timeout
|
|
|
|
for trail in trails:
|
|
if is_instance_valid(trail):
|
|
trail.speed_scale = 1 # Resume movement
|