diff --git a/weapons/space_gun/projectile.tscn b/weapons/space_gun/projectile.tscn index b96847a..2ed705d 100644 --- a/weapons/space_gun/projectile.tscn +++ b/weapons/space_gun/projectile.tscn @@ -1,7 +1,15 @@ -[gd_scene load_steps=5 format=3 uid="uid://dn1tcakam5egs"] +[gd_scene load_steps=7 format=3 uid="uid://dn1tcakam5egs"] [ext_resource type="Script" path="res://weapons/space_gun/projectile.gd" id="1_4j1dp"] [ext_resource type="PackedScene" uid="uid://8atq41j7wd55" path="res://weapons/space_gun/projectile_explosion.tscn" id="2_llml6"] +[ext_resource type="Script" path="res://weapons/space_gun/projectile_trail.gd" id="3_ygqbh"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_4a265"] +transparency = 1 +blend_mode = 1 +cull_mode = 2 +shading_mode = 0 +vertex_color_use_as_albedo = true [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_o6j55"] albedo_color = Color(0, 0.498039, 0.854902, 1) @@ -15,6 +23,15 @@ radius = 0.15 script = ExtResource("1_4j1dp") EXPLOSION = ExtResource("2_llml6") +[node name="Trail3D" type="MeshInstance3D" parent="."] +material_override = SubResource("StandardMaterial3D_4a265") +script = ExtResource("3_ygqbh") +_from_width = 0.15 +_scale_acceleration = 0.5 +_lifespan = 0.25 +_start_color = Color(0, 0.498039, 0.854902, 1) +_end_color = Color(1, 1, 1, 0) + [node name="Mesh" type="CSGSphere3D" parent="."] transform = Transform3D(1, 0, 0, 0, 0.2, 0, 0, 0, 1, 0, 0, 0) radius = 0.15 diff --git a/weapons/space_gun/projectile_trail.gd b/weapons/space_gun/projectile_trail.gd new file mode 100644 index 0000000..fc007fe --- /dev/null +++ b/weapons/space_gun/projectile_trail.gd @@ -0,0 +1,80 @@ +class_name Trail3D extends MeshInstance3D + +var _points = [] # 3D points of trail +var _widths = [] # Calculated widths of trail +var _lifespans = [] # Trail point lifespans + +@export var _trail_enabled : bool = true # Is trail shown? + +@export var _from_width : float = 0.5 # Starting width +@export var _to_width : float = 0.0 # Ending width + +@export_range(0.5, 1.5) var _scale_acceleration : float = 1.0 # Scaling speed + +@export var _motion_delta : float = 0.1 # Smoothness of trail +@export var _lifespan : float = 1.0 # Duration of trail + +@export var _start_color : Color = Color(1.0, 1.0, 1.0, 1.0) # Start color +@export var _end_color : Color = Color(1.0, 1.0, 1.0, 1.0) # End color + +var _old_pos : Vector3 # Previous pos + +func _append_point(): + _points.append(get_global_transform().origin) + _widths.append([ + get_global_transform().basis.x * _from_width, + get_global_transform().basis.x * _from_width - get_global_transform().basis.x * _to_width + ]) + _lifespans.append(0.0) + +func _remove_point(i): + _points.remove_at(i) + _widths.remove_at(i) + _lifespans.remove_at(i) + +func _ready(): + _old_pos = get_global_transform().origin + mesh = ImmediateMesh.new() + +func _process(delta): + if(_old_pos - get_global_transform().origin).length() > _motion_delta and _trail_enabled: + _append_point() # Create new point + _old_pos = get_global_transform().origin # Update previous position to current position coordinates + + # Update the lifespan + var p = 0 + var max_points = _points.size() + while p < max_points: + _lifespans[p] += delta + if _lifespans[p] > _lifespan: + _remove_point(p) + p -= 1 + if (p < 0): p = 0 + + max_points = _points.size() + p += 1 + + mesh.clear_surfaces() + + # If less than 2 points, stop rendering trail + if _points.size() < 2: + return + + # Render new mesh for each point + mesh.surface_begin(Mesh.PRIMITIVE_TRIANGLE_STRIP) + + for i in range(_points.size()): + var t = float(i) / (_points.size() - 1.0) + var curr_color = _start_color.lerp(_end_color, 1 - t) + mesh.surface_set_color(curr_color) + + var curr_width = _widths[i][0] - pow(1 - t, _scale_acceleration) * _widths[i][1] + + var t0 = i / _points.size() + var t1 = t + + mesh.surface_set_uv(Vector2(t0, 0)) + mesh.surface_add_vertex(to_local(_points[i] + curr_width)) + mesh.surface_set_uv(Vector2(t1, 1)) + mesh.surface_add_vertex(to_local(_points[i] - curr_width)) + mesh.surface_end()