generated from krampus/template-godot4
Splatter effect scales with source node scale
This commit is contained in:
parent
eba7d3d06b
commit
9d8f1f1767
@ -13,12 +13,6 @@ extends Node3D
|
|||||||
@onready var prop_test_spawn_point: Marker3D = %PropTestSpawnPoint
|
@onready var prop_test_spawn_point: Marker3D = %PropTestSpawnPoint
|
||||||
@onready var item_test_spawn_point: Marker3D = %ItemTestSpawnPoint
|
@onready var item_test_spawn_point: Marker3D = %ItemTestSpawnPoint
|
||||||
|
|
||||||
static var nodule_scene: PackedScene = load("res://src/world/gunk_node/grunk_nodule.tscn")
|
|
||||||
static var alarm_scene: PackedScene = load("res://src/world/mechanics/alarm/gunk_alarm.tscn")
|
|
||||||
static var signal_test_scene: PackedScene = load("res://levels/mechanic_test/signal_test.tscn")
|
|
||||||
static var prop_test_scene: PackedScene = load("res://levels/mechanic_test/prop_test.tscn")
|
|
||||||
static var item_test_scene: PackedScene = load("res://levels/mechanic_test/item_test.tscn")
|
|
||||||
|
|
||||||
|
|
||||||
func reset() -> void:
|
func reset() -> void:
|
||||||
print("Resetting level!")
|
print("Resetting level!")
|
||||||
@ -26,6 +20,10 @@ func reset() -> void:
|
|||||||
Callable(bulkhead, "close").call()
|
Callable(bulkhead, "close").call()
|
||||||
Callable(open_switch, "enable").call()
|
Callable(open_switch, "enable").call()
|
||||||
Callable(close_switch, "disable").call()
|
Callable(close_switch, "disable").call()
|
||||||
|
|
||||||
|
var signal_test_scene: PackedScene = load("res://levels/mechanic_test/signal_test.tscn")
|
||||||
|
var prop_test_scene: PackedScene = load("res://levels/mechanic_test/prop_test.tscn")
|
||||||
|
var item_test_scene: PackedScene = load("res://levels/mechanic_test/item_test.tscn")
|
||||||
_do_spawn(signal_test_spawn_point, signal_test_scene)
|
_do_spawn(signal_test_spawn_point, signal_test_scene)
|
||||||
_do_spawn(prop_test_spawn_point, prop_test_scene)
|
_do_spawn(prop_test_spawn_point, prop_test_scene)
|
||||||
_do_spawn(item_test_spawn_point, item_test_scene)
|
_do_spawn(item_test_spawn_point, item_test_scene)
|
||||||
@ -39,10 +37,12 @@ func _do_spawn(spawn_point: Node3D, scene: PackedScene) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func spawn_nodule() -> void:
|
func spawn_nodule() -> void:
|
||||||
|
var nodule_scene: PackedScene = load("res://src/world/gunk_node/grunk_nodule.tscn")
|
||||||
_do_spawn(nodule_spawn_point, nodule_scene)
|
_do_spawn(nodule_spawn_point, nodule_scene)
|
||||||
|
|
||||||
|
|
||||||
func spawn_alarm() -> void:
|
func spawn_alarm() -> void:
|
||||||
|
var alarm_scene: PackedScene = load("res://src/world/mechanics/alarm/gunk_alarm.tscn")
|
||||||
_do_spawn(alarm_spawn_point, alarm_scene)
|
_do_spawn(alarm_spawn_point, alarm_scene)
|
||||||
|
|
||||||
|
|
||||||
|
34
src/effects/grunk_splatter/grunk_splatter.gd
Normal file
34
src/effects/grunk_splatter/grunk_splatter.gd
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
class_name GrunkSplatter extends GPUParticles3D
|
||||||
|
## Splatter effect with adjustable volume
|
||||||
|
|
||||||
|
const BASE_VOLUME := -12.0
|
||||||
|
const SCALE_FACTOR := 4.0
|
||||||
|
|
||||||
|
const SCENE := preload("res://src/effects/grunk_splatter/grunk_splatter.tscn")
|
||||||
|
|
||||||
|
@export var effect_scale := 1.0
|
||||||
|
|
||||||
|
@onready var splatter_sfx: AudioStreamPlayer3D = %SplatterSFX
|
||||||
|
@onready var sub_splatter: GPUParticles3D = %SubSplatter
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
splatter_sfx.volume_db = BASE_VOLUME + SCALE_FACTOR * log(effect_scale) / log(2)
|
||||||
|
scale = Vector3.ONE * effect_scale
|
||||||
|
|
||||||
|
# Scale particles themselves
|
||||||
|
_scale_particles(self)
|
||||||
|
_scale_particles(sub_splatter)
|
||||||
|
|
||||||
|
|
||||||
|
func _scale_particles(emitter: GPUParticles3D) -> void:
|
||||||
|
var mat := emitter.process_material as ParticleProcessMaterial
|
||||||
|
mat.scale_max = effect_scale
|
||||||
|
mat.scale_min = effect_scale
|
||||||
|
|
||||||
|
|
||||||
|
static func build(_effect_scale: float = 1.0) -> GrunkSplatter:
|
||||||
|
var instance: GrunkSplatter = SCENE.instantiate()
|
||||||
|
instance.effect_scale = _effect_scale
|
||||||
|
return instance
|
1
src/effects/grunk_splatter/grunk_splatter.gd.uid
Normal file
1
src/effects/grunk_splatter/grunk_splatter.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://di5b65ehsfatj
|
@ -1,7 +1,8 @@
|
|||||||
[gd_scene load_steps=22 format=3 uid="uid://xlt78xc1tmkl"]
|
[gd_scene load_steps=23 format=3 uid="uid://xlt78xc1tmkl"]
|
||||||
|
|
||||||
[ext_resource type="Texture2D" uid="uid://cgwgmxwjgwbwr" path="res://assets/particles/splatter_2.png" id="1_5xu2x"]
|
[ext_resource type="Texture2D" uid="uid://cgwgmxwjgwbwr" path="res://assets/particles/splatter_2.png" id="1_5xu2x"]
|
||||||
[ext_resource type="Texture2D" uid="uid://bhoai6xv53tqm" path="res://assets/particles/splatter_1.png" id="2_bt63p"]
|
[ext_resource type="Texture2D" uid="uid://bhoai6xv53tqm" path="res://assets/particles/splatter_1.png" id="2_bt63p"]
|
||||||
|
[ext_resource type="Script" uid="uid://di5b65ehsfatj" path="res://src/effects/grunk_splatter/grunk_splatter.gd" id="2_grvat"]
|
||||||
[ext_resource type="AudioStream" uid="uid://di0j2xhgfc78s" path="res://assets/sfx/grunk/splat1.wav" id="3_t00bd"]
|
[ext_resource type="AudioStream" uid="uid://di0j2xhgfc78s" path="res://assets/sfx/grunk/splat1.wav" id="3_t00bd"]
|
||||||
[ext_resource type="AudioStream" uid="uid://d1w5gfmjj7tjk" path="res://assets/sfx/grunk/splat2.wav" id="4_2iem1"]
|
[ext_resource type="AudioStream" uid="uid://d1w5gfmjj7tjk" path="res://assets/sfx/grunk/splat2.wav" id="4_2iem1"]
|
||||||
[ext_resource type="Script" uid="uid://c5o1d2shq2qig" path="res://src/world/game_sound/game_sound_emitter.gd" id="5_2iem1"]
|
[ext_resource type="Script" uid="uid://c5o1d2shq2qig" path="res://src/world/game_sound/game_sound_emitter.gd" id="5_2iem1"]
|
||||||
@ -22,6 +23,7 @@ point_count = 2
|
|||||||
curve = SubResource("Curve_y6klh")
|
curve = SubResource("Curve_y6klh")
|
||||||
|
|
||||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_5xu2x"]
|
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_5xu2x"]
|
||||||
|
resource_local_to_scene = true
|
||||||
lifetime_randomness = 0.57
|
lifetime_randomness = 0.57
|
||||||
emission_shape = 1
|
emission_shape = 1
|
||||||
emission_sphere_radius = 1.0
|
emission_sphere_radius = 1.0
|
||||||
@ -65,6 +67,7 @@ point_count = 2
|
|||||||
curve = SubResource("Curve_t00bd")
|
curve = SubResource("Curve_t00bd")
|
||||||
|
|
||||||
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_2iem1"]
|
[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_2iem1"]
|
||||||
|
resource_local_to_scene = true
|
||||||
lifetime_randomness = 0.55
|
lifetime_randomness = 0.55
|
||||||
emission_shape = 1
|
emission_shape = 1
|
||||||
emission_sphere_radius = 0.9
|
emission_sphere_radius = 0.9
|
||||||
@ -112,8 +115,10 @@ one_shot = true
|
|||||||
explosiveness = 0.45
|
explosiveness = 0.45
|
||||||
process_material = SubResource("ParticleProcessMaterial_5xu2x")
|
process_material = SubResource("ParticleProcessMaterial_5xu2x")
|
||||||
draw_pass_1 = SubResource("QuadMesh_y6klh")
|
draw_pass_1 = SubResource("QuadMesh_y6klh")
|
||||||
|
script = ExtResource("2_grvat")
|
||||||
|
|
||||||
[node name="SubSplatter" type="GPUParticles3D" parent="."]
|
[node name="SubSplatter" type="GPUParticles3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
sorting_offset = 9.0
|
sorting_offset = 9.0
|
||||||
emitting = false
|
emitting = false
|
||||||
amount = 4
|
amount = 4
|
||||||
@ -131,8 +136,9 @@ one_shot = true
|
|||||||
autostart = true
|
autostart = true
|
||||||
|
|
||||||
[node name="SplatterSFX" type="AudioStreamPlayer3D" parent="."]
|
[node name="SplatterSFX" type="AudioStreamPlayer3D" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
stream = SubResource("AudioStreamRandomizer_6adkd")
|
stream = SubResource("AudioStreamRandomizer_6adkd")
|
||||||
volume_db = -16.0
|
volume_db = -12.0
|
||||||
unit_size = 6.0
|
unit_size = 6.0
|
||||||
autoplay = true
|
autoplay = true
|
||||||
bus = &"SFX"
|
bus = &"SFX"
|
@ -25,9 +25,6 @@ const MIN_CHITTER_INTERVAL := 4.0
|
|||||||
@export var chitter_time_mean := 60.0
|
@export var chitter_time_mean := 60.0
|
||||||
@export var chitter_time_st_dev := 30.0
|
@export var chitter_time_st_dev := 30.0
|
||||||
|
|
||||||
@export_category("Game Scenes")
|
|
||||||
@export var splatter_scene: PackedScene
|
|
||||||
|
|
||||||
@onready var mesh_instance: MeshInstance3D = %MeshInstance3D
|
@onready var mesh_instance: MeshInstance3D = %MeshInstance3D
|
||||||
|
|
||||||
@onready var chitter_sfx: AudioStreamPlayer3D = %ChitterSFX
|
@onready var chitter_sfx: AudioStreamPlayer3D = %ChitterSFX
|
||||||
@ -53,13 +50,6 @@ func _process(delta: float) -> void:
|
|||||||
shader.set_shader_parameter("vertex_inflation", pow(damage * jitter_inflation_factor, 3))
|
shader.set_shader_parameter("vertex_inflation", pow(damage * jitter_inflation_factor, 3))
|
||||||
|
|
||||||
|
|
||||||
func _destroy() -> void:
|
|
||||||
var splatter: GPUParticles3D = splatter_scene.instantiate()
|
|
||||||
add_sibling(splatter)
|
|
||||||
splatter.global_position = global_position
|
|
||||||
splatter.emitting = true
|
|
||||||
|
|
||||||
|
|
||||||
func start_chitter_timer() -> void:
|
func start_chitter_timer() -> void:
|
||||||
var interval := maxf(MIN_CHITTER_INTERVAL, randfn(chitter_time_mean, chitter_time_st_dev))
|
var interval := maxf(MIN_CHITTER_INTERVAL, randfn(chitter_time_mean, chitter_time_st_dev))
|
||||||
chitter_timer.start(interval)
|
chitter_timer.start(interval)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
[gd_scene load_steps=12 format=4 uid="uid://2yqi5u5eo025"]
|
[gd_scene load_steps=11 format=4 uid="uid://2yqi5u5eo025"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://07t7yhijru8f" path="res://src/world/gunk_node/grunk_nodule.gd" id="1_iyr82"]
|
[ext_resource type="Script" uid="uid://07t7yhijru8f" path="res://src/world/gunk_node/grunk_nodule.gd" id="1_iyr82"]
|
||||||
[ext_resource type="PackedScene" uid="uid://xlt78xc1tmkl" path="res://src/effects/grunk_splatter.tscn" id="2_m8r0a"]
|
|
||||||
[ext_resource type="Material" uid="uid://bmab6i16v748m" path="res://assets/materials/grunk_jittery.material" id="3_eu6j6"]
|
[ext_resource type="Material" uid="uid://bmab6i16v748m" path="res://assets/materials/grunk_jittery.material" id="3_eu6j6"]
|
||||||
[ext_resource type="AudioStream" uid="uid://bb560r2wvjfht" path="res://assets/sfx/grunk/greeble1.wav" id="4_7fplw"]
|
[ext_resource type="AudioStream" uid="uid://bb560r2wvjfht" path="res://assets/sfx/grunk/greeble1.wav" id="4_7fplw"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dunakapj3mb0h" path="res://assets/sfx/grunk/greeble2.wav" id="5_omayi"]
|
[ext_resource type="AudioStream" uid="uid://dunakapj3mb0h" path="res://assets/sfx/grunk/greeble2.wav" id="5_omayi"]
|
||||||
@ -55,7 +54,6 @@ stream_3/stream = ExtResource("7_4kci5")
|
|||||||
collision_layer = 36
|
collision_layer = 36
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
script = ExtResource("1_iyr82")
|
script = ExtResource("1_iyr82")
|
||||||
splatter_scene = ExtResource("2_m8r0a")
|
|
||||||
durability = 3.0
|
durability = 3.0
|
||||||
metadata/_custom_type_script = "uid://bypgxi0gy56yk"
|
metadata/_custom_type_script = "uid://bypgxi0gy56yk"
|
||||||
|
|
||||||
|
@ -13,6 +13,9 @@ const JITTER_FADE_RATE := 0.8
|
|||||||
## Value added to the player's grunk total on destruction.
|
## Value added to the player's grunk total on destruction.
|
||||||
@export var value := 1000.0
|
@export var value := 1000.0
|
||||||
|
|
||||||
|
## Scale factor applied to the size and volume of the splatter effect on destruction.
|
||||||
|
@export var splatter_scale := 1.0
|
||||||
|
|
||||||
var _sustained_damage := 0.0
|
var _sustained_damage := 0.0
|
||||||
var _hit_this_frame := false
|
var _hit_this_frame := false
|
||||||
|
|
||||||
@ -55,6 +58,9 @@ func collect() -> void:
|
|||||||
## Derived types should override `_destroy` as a lifecycle method.
|
## Derived types should override `_destroy` as a lifecycle method.
|
||||||
func destroy() -> void:
|
func destroy() -> void:
|
||||||
Game.manager.collect_grunk(value)
|
Game.manager.collect_grunk(value)
|
||||||
|
var splatter := GrunkSplatter.build(splatter_scale * scale.x)
|
||||||
|
add_sibling(splatter)
|
||||||
|
splatter.global_position = global_position
|
||||||
_destroy()
|
_destroy()
|
||||||
destroyed.emit()
|
destroyed.emit()
|
||||||
queue_free()
|
queue_free()
|
||||||
|
@ -103,7 +103,7 @@ seamless = true
|
|||||||
seamless_blend_skirt = 0.5
|
seamless_blend_skirt = 0.5
|
||||||
noise = ExtResource("7_aqwgb")
|
noise = ExtResource("7_aqwgb")
|
||||||
|
|
||||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_qmfft"]
|
[sub_resource type="ShaderMaterial" id="ShaderMaterial_umjw2"]
|
||||||
resource_local_to_scene = true
|
resource_local_to_scene = true
|
||||||
render_priority = 0
|
render_priority = 0
|
||||||
shader = ExtResource("6_6agnv")
|
shader = ExtResource("6_6agnv")
|
||||||
@ -237,7 +237,7 @@ skeleton = NodePath("GunkHallBody")
|
|||||||
[node name="GunkHallBody" parent="GunkHall" instance=ExtResource("4_7v7un")]
|
[node name="GunkHallBody" parent="GunkHall" instance=ExtResource("4_7v7un")]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
initial_mask = ExtResource("5_llot1")
|
initial_mask = ExtResource("5_llot1")
|
||||||
source_gunk_material = SubResource("ShaderMaterial_qmfft")
|
source_gunk_material = SubResource("ShaderMaterial_umjw2")
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="GunkHall/GunkHallBody"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="GunkHall/GunkHallBody"]
|
||||||
shape = SubResource("ConcavePolygonShape3D_qjnj2")
|
shape = SubResource("ConcavePolygonShape3D_qjnj2")
|
||||||
|
@ -7,8 +7,6 @@ signal triggered
|
|||||||
@export var quick_connect_to: SignalNode:
|
@export var quick_connect_to: SignalNode:
|
||||||
set = _editor_connect
|
set = _editor_connect
|
||||||
|
|
||||||
@export var splatter_scene: PackedScene
|
|
||||||
|
|
||||||
# NOTE
|
# NOTE
|
||||||
# trigger oscillation animation was generated using the formula
|
# trigger oscillation animation was generated using the formula
|
||||||
# f(x) = e^(-0.25x) * cos(x * pi / 2 - pi/2) + 1 for x in {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 20}
|
# f(x) = e^(-0.25x) * cos(x * pi / 2 - pi/2) + 1 for x in {0, 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 20}
|
||||||
@ -27,10 +25,6 @@ func trigger() -> void:
|
|||||||
cooldown_timer.start()
|
cooldown_timer.start()
|
||||||
|
|
||||||
|
|
||||||
func _destroy() -> void:
|
|
||||||
add_sibling(splatter_scene.instantiate())
|
|
||||||
|
|
||||||
|
|
||||||
func _editor_connect(node: SignalNode) -> void:
|
func _editor_connect(node: SignalNode) -> void:
|
||||||
triggered.connect(node.trigger, CONNECT_PERSIST)
|
triggered.connect(node.trigger, CONNECT_PERSIST)
|
||||||
self.notify_property_list_changed()
|
self.notify_property_list_changed()
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
[gd_scene load_steps=10 format=3 uid="uid://kctp5erogwcb"]
|
[gd_scene load_steps=9 format=3 uid="uid://kctp5erogwcb"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bde7cglaqobkd" path="res://src/world/mechanics/listener/listener.gd" id="1_htscg"]
|
[ext_resource type="Script" uid="uid://bde7cglaqobkd" path="res://src/world/mechanics/listener/listener.gd" id="1_htscg"]
|
||||||
[ext_resource type="PackedScene" uid="uid://xlt78xc1tmkl" path="res://src/effects/grunk_splatter.tscn" id="2_2ibh1"]
|
|
||||||
[ext_resource type="Script" uid="uid://cfsiyhhrcua6o" path="res://src/world/game_sound/game_sound_listener.gd" id="2_htscg"]
|
[ext_resource type="Script" uid="uid://cfsiyhhrcua6o" path="res://src/world/game_sound/game_sound_listener.gd" id="2_htscg"]
|
||||||
|
|
||||||
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_2ibh1"]
|
[sub_resource type="ConcavePolygonShape3D" id="ConcavePolygonShape3D_2ibh1"]
|
||||||
@ -58,7 +57,6 @@ _data = {
|
|||||||
collision_layer = 36
|
collision_layer = 36
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
script = ExtResource("1_htscg")
|
script = ExtResource("1_htscg")
|
||||||
splatter_scene = ExtResource("2_2ibh1")
|
|
||||||
durability = 3.0
|
durability = 3.0
|
||||||
value = 4000.0
|
value = 4000.0
|
||||||
metadata/_custom_type_script = "uid://bypgxi0gy56yk"
|
metadata/_custom_type_script = "uid://bypgxi0gy56yk"
|
||||||
|
@ -8,9 +8,11 @@ signal triggered
|
|||||||
## Emitted when `pulse` is called, after a short delay.
|
## Emitted when `pulse` is called, after a short delay.
|
||||||
signal pulsed
|
signal pulsed
|
||||||
|
|
||||||
|
@export_category("Editor Tools")
|
||||||
@export var quick_connect_to: SignalNode:
|
@export var quick_connect_to: SignalNode:
|
||||||
set = _editor_connect
|
set = _editor_connect
|
||||||
|
|
||||||
|
@export_category("Game Scenes")
|
||||||
@export var editor_arrow_scene: PackedScene
|
@export var editor_arrow_scene: PackedScene
|
||||||
|
|
||||||
var _busy := false
|
var _busy := false
|
||||||
|
@ -115,6 +115,7 @@ collision_mask = 0
|
|||||||
script = ExtResource("1_rdv5j")
|
script = ExtResource("1_rdv5j")
|
||||||
editor_arrow_scene = ExtResource("2_nfkbq")
|
editor_arrow_scene = ExtResource("2_nfkbq")
|
||||||
value = 800.0
|
value = 800.0
|
||||||
|
splatter_scale = 0.2
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
gi_mode = 2
|
gi_mode = 2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user