diff --git a/scenes/marble.tscn b/scenes/marble.tscn index d6a1e14..215bdb5 100644 --- a/scenes/marble.tscn +++ b/scenes/marble.tscn @@ -1,23 +1,12 @@ -[gd_scene load_steps=12 format=3 uid="uid://4g5aorgnd1hu"] +[gd_scene load_steps=9 format=3 uid="uid://4g5aorgnd1hu"] [ext_resource type="Script" path="res://scripts/marble.gd" id="1"] [ext_resource type="Material" uid="uid://5gxm1ehx7waa" path="res://resources/materials/xray_marble.tres" id="2"] -[ext_resource type="Script" path="res://scripts/lod/lod_spatial.gd" id="2_5e2c6"] [ext_resource type="Script" path="res://scripts/roll_sound.gd" id="4"] [ext_resource type="AudioStream" uid="uid://3hc6gfblh3gf" path="res://assets/sounds/sfx/roll.wav" id="4_d1o80"] [ext_resource type="AudioStream" uid="uid://b7ga03rbxi6qs" path="res://assets/sounds/sfx/hit.wav" id="6_iicuw"] [ext_resource type="AudioStream" uid="uid://c44julexev4dj" path="res://assets/sounds/explosion/bomb.ogg" id="7_1gve1"] -[sub_resource type="SphereMesh" id="1"] -radius = 0.3 -height = 0.6 - -[sub_resource type="SphereMesh" id="5"] -radius = 0.3 -height = 0.6 -radial_segments = 32 -rings = 16 - [sub_resource type="SphereMesh" id="4"] radius = 0.3 height = 0.6 @@ -33,24 +22,9 @@ max_contacts_reported = 10000 contact_monitor = true script = ExtResource("1") -[node name="LODSpatial" type="Node3D" parent="."] -script = ExtResource("2_5e2c6") - -[node name="Ball-0" type="MeshInstance3D" parent="LODSpatial"] -mesh = SubResource("1") -skeleton = NodePath("../..") -surface_material_override/0 = ExtResource("2") - -[node name="Ball-1" type="MeshInstance3D" parent="LODSpatial"] -visible = false -mesh = SubResource("5") -skeleton = NodePath("../..") -surface_material_override/0 = ExtResource("2") - -[node name="Ball-2" type="MeshInstance3D" parent="LODSpatial"] -visible = false +[node name="Ball" type="MeshInstance3D" parent="."] +unique_name_in_owner = true mesh = SubResource("4") -skeleton = NodePath("../..") surface_material_override/0 = ExtResource("2") [node name="CollisionShape" type="CollisionShape3D" parent="."] diff --git a/scripts/lod/lod_particles.gd b/scripts/lod/lod_particles.gd deleted file mode 100644 index 7a8d7fc..0000000 --- a/scripts/lod/lod_particles.gd +++ /dev/null @@ -1,51 +0,0 @@ -class_name LODParticles -extends GPUParticles3D - -# If `false`, LOD won't update anymore. This can be used for performance comparison -# purposes. -@export var enable_lod := true - -# The maximum particle emitting distance in units. -# Past this distance, particles will no longer emit. -@export_range(0.0, 1000.0, 0.1) var max_emit_distance := 50 - -# The rate at which LODs will be updated (in seconds). Lower values are more reactive -# but use more CPU, which is especially noticeable with large amounts of LOD-enabled nodes. -# Set this accordingly depending on your camera movement speed. -# The default value should suit most projects already. -# Note: Slow cameras don't need to have LOD-enabled objects update their status often. -# This can overridden by setting the project setting `lod/_refresh_rate`. -var _refresh_rate := 0.25 - -# The internal refresh timer. -var _timer := 0.0 - - -func _ready() -> void: - if ProjectSettings.has_setting("lod/_refresh_rate"): - _refresh_rate = ProjectSettings.get_setting("lod/_refresh_rate") - - # Add random jitter to the timer to ensure LODs don't all swap at the same time. - randomize() - _timer += randf_range(0, _refresh_rate) - - -# Despite LOD not being related to physics, we chose to run in `_physics_process()` -# to minimize the amount of method calls per second (and therefore decrease CPU usage). -func _physics_process(delta: float) -> void: - if not enable_lod: - return - - # We need a camera to do the rest. - var camera := get_viewport().get_camera_3d() as Camera3D - if camera == null: - return - - if _timer <= _refresh_rate: - _timer += delta - return - - _timer = 0.0 - - var distance := camera.global_transform.origin.distance_to(global_transform.origin) + lod_bias - emitting = distance < max_emit_distance diff --git a/scripts/lod/lod_spatial.gd b/scripts/lod/lod_spatial.gd deleted file mode 100644 index 16afe05..0000000 --- a/scripts/lod/lod_spatial.gd +++ /dev/null @@ -1,85 +0,0 @@ -class_name LODSpatial -extends Node3D - -# If `false`, LOD won't update anymore. This can be used for performance comparison -# purposes. -@export var enable_lod := true - -# The maximum LOD 0 (high quality) distance in units. -@export_range(0.0, 1000.0, 0.1) var lod_0_max_distance := 10 - -# The maximum LOD 1 (medium quality) distance in units. -@export_range(0.0, 1000.0, 0.1) var lod_1_max_distance := 25 - -# The maximum LOD 2 (low quality) distance in units. -# Past this distance, all LOD variants are hidden. -@export_range(0.0, 1000.0, 0.1) var lod_2_max_distance := 100 - -# The rate at which LODs will be updated (in seconds). Lower values are more reactive -# but use more CPU, which is especially noticeable with large amounts of LOD-enabled nodes. -# Set this accordingly depending on your camera movement speed. -# The default value should suit most projects already. -# Note: Slow cameras don't need to have LOD-enabled objects update their status often. -# This can overridden by setting the project setting `lod/refresh_rate`. -var _refresh_rate := 0.25 - -# The LOD bias in units. -# Positive values will decrease the detail level and improve performance. -# Negative values will improve visual appearance at the cost of performance. -# This can overridden by setting the project setting `lod/bias`. -var _lod_bias := 0.0 - -# The internal refresh timer. -var _timer := 0.0 - - -func _ready() -> void: - if ProjectSettings.has_setting(&"lod/spatial_bias"): - _lod_bias = ProjectSettings.get_setting(&"lod/spatial_bias") - if ProjectSettings.has_setting(&"lod/refresh_rate"): - _refresh_rate = ProjectSettings.get_setting(&"lod/refresh_rate") - - # Add random jitter to the timer to ensure LODs don't all swap at the same time. - randomize() - _timer += randf_range(0, _refresh_rate) - - -# Despite LOD not being related to physics, we chose to run in `_physics_process()` -# to minimize the amount of method calls per second (and therefore decrease CPU usage). -func _physics_process(delta: float) -> void: - if not enable_lod: - return - - # We need a camera to do the rest. - var camera := get_viewport().get_camera_3d() - if camera == null: - return - - if _timer <= _refresh_rate: - _timer += delta - return - - _timer = 0.0 - - var distance := camera.global_transform.origin.distance_to(global_transform.origin) + _lod_bias - # The LOD level to choose (lower is more detailed). - var lod: int - if distance < lod_0_max_distance: - lod = 0 - elif distance < lod_1_max_distance: - lod = 1 - elif distance < lod_2_max_distance: - lod = 2 - else: - # Hide the LOD object entirely. - lod = 3 - - for node in get_children(): - # `-lod` also matches `-lod0`, `-lod1`, `-lod2`, … - if node.has_method(&"set_visible"): - if "-lod0" in node.name: - node.visible = lod == 0 - if "-lod1" in node.name: - node.visible = lod == 1 - if "-lod2" in node.name: - node.visible = lod == 2 diff --git a/scripts/marble.gd b/scripts/marble.gd index 6477486..e782362 100644 --- a/scripts/marble.gd +++ b/scripts/marble.gd @@ -14,6 +14,7 @@ var _checkpoint_count := 0 @onready var _name := get_node(^"%Name") as Label3D @onready var _bomb_sound = get_node(^"%BombSound") @onready var _score = get_node(^"%Score") +@onready var _ball_mesh := get_node(^"%Ball") func _ready() -> void: @@ -23,16 +24,15 @@ func _ready() -> void: # Set material color var color = Color(randf(), randf(), randf()) - for i in range(3): - var x_ray_material: StandardMaterial3D = ( - get_node("LODSpatial/Ball-%d" % i).get_active_material(0) - ) - x_ray_material.set_albedo(color) - var toon_material: StandardMaterial3D = x_ray_material.get_next_pass() - toon_material.set_albedo(color) + var x_ray_material: StandardMaterial3D = ( + _ball_mesh.get_active_material(0) + ) + x_ray_material.set_albedo(color) + var toon_material: StandardMaterial3D = x_ray_material.get_next_pass() + toon_material.set_albedo(color) # toon_material.set_shader_parameter(&"albedo", color) - x_ray_material.set_next_pass(toon_material) - get_node("LODSpatial/Ball-%d" % i).set_surface_override_material(0, x_ray_material) + x_ray_material.set_next_pass(toon_material) + _ball_mesh.set_surface_override_material(0, x_ray_material) # Set collision mask var collision_enabled = SettingsManager.get_value(&"marbles", &"collision_enabled") as bool