78 lines
1.8 KiB
GDScript
78 lines
1.8 KiB
GDScript
class_name Projectile
|
|
extends Area3D
|
|
|
|
const HEIGHT: float = 1
|
|
const MAX_STRETCH: float = 0.75
|
|
|
|
@export var _speed_stretch_factor: float = 100
|
|
|
|
@export var _collision_debug_material: Material
|
|
|
|
var _start_position: Vector3
|
|
var _velocity: Vector3
|
|
var _lifetime: float
|
|
var _size: float = 0.25
|
|
|
|
var _life_timer: float
|
|
|
|
var _debug_collision_shapes := DebugCollisionShapes.new()
|
|
|
|
@onready var _model_base: Node3D = $Model
|
|
@onready var _model_mesh: MeshInstance3D = $Model/ProjectileMesh
|
|
|
|
|
|
func _ready() -> void:
|
|
_life_timer = _lifetime
|
|
_debug_collision_shapes.init(get_children(), self, _collision_debug_material)
|
|
global_position = _start_position
|
|
body_entered.connect(_on_body_entered)
|
|
_model_mesh.rotation = Vector3(
|
|
randf_range(0, TAU), randf_range(0, TAU), randf_range(0, TAU)
|
|
)
|
|
_model_mesh.scale = Vector3.ONE * _size
|
|
|
|
|
|
func _physics_process(delta: float) -> void:
|
|
if _life_timer <= 0:
|
|
queue_free()
|
|
|
|
_life_timer -= delta
|
|
global_position += _velocity * delta
|
|
look_at(global_position + _velocity, Vector3.UP, true)
|
|
|
|
var speed_squash := clampf(
|
|
_velocity.length() / _speed_stretch_factor, 0, MAX_STRETCH
|
|
)
|
|
_model_base.scale = Vector3(
|
|
1 - speed_squash, 1 - speed_squash, 1 + speed_squash
|
|
)
|
|
|
|
|
|
func init(velocity: Vector3, start_position: Vector3, lifetime: float = 10) -> void:
|
|
_velocity = velocity
|
|
_start_position = start_position
|
|
_lifetime = lifetime
|
|
|
|
|
|
func set_velocity(velocity: Vector3) -> void:
|
|
_velocity = velocity
|
|
_life_timer = _lifetime
|
|
|
|
|
|
func _on_body_entered(node: Node3D) -> void:
|
|
if node is Player:
|
|
queue_free()
|
|
return
|
|
|
|
if node is CollisionObject3D:
|
|
var collision_node := node as CollisionObject3D
|
|
if collision_node.collision_layer & 1:
|
|
queue_free()
|
|
return
|
|
|
|
if node is CSGCombiner3D:
|
|
var collision_node := node as CSGCombiner3D
|
|
if collision_node.collision_layer & 1:
|
|
queue_free()
|
|
return
|