diff --git a/scenes/main.tscn b/scenes/main.tscn index 561fe55..a7623f3 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -1,67 +1,13 @@ -[gd_scene load_steps=22 format=3 uid="uid://clq7nox1juh3a"] +[gd_scene load_steps=9 format=3 uid="uid://clq7nox1juh3a"] [ext_resource type="Environment" uid="uid://c3bs0wfxpri8g" path="res://scenes/main-environment.tres" id="1_q4t1r"] -[ext_resource type="Script" uid="uid://bqite16pastgo" path="res://scripts/vehicle.gd" id="2_xjb8m"] -[ext_resource type="Texture2D" uid="uid://c026qrhqxgw3n" path="res://sprites/smoke.png" id="4_h8cj5"] -[ext_resource type="PackedScene" uid="uid://bynb5jk1d478y" path="res://models/vehicle-truck-yellow.glb" id="4_ya4ey"] +[ext_resource type="PackedScene" uid="uid://badoy1c127yhf" path="res://scenes/vehicle.tscn" id="2_o6xl0"] [ext_resource type="Script" uid="uid://b24bstassw26s" path="res://scripts/view.gd" id="5_0lrhn"] -[ext_resource type="AudioStream" uid="uid://2in1jtv5bh0y" path="res://audio/skid.ogg" id="5_choun"] -[ext_resource type="AudioStream" uid="uid://j6x2is8pyt8y" path="res://audio/engine.ogg" id="6_choun"] [ext_resource type="MeshLibrary" uid="uid://b6myd2b7l2o2j" path="res://models/Library/mesh-library.tres" id="8_eg7gk"] [ext_resource type="PackedScene" uid="uid://c44tfiddyjjm1" path="res://models/vehicle-truck-green.glb" id="9_cmq2j"] [ext_resource type="PackedScene" uid="uid://c5e64mpylh1ge" path="res://models/vehicle-truck-purple.glb" id="10_p3c1o"] [ext_resource type="PackedScene" uid="uid://b34e2pvbemfac" path="res://models/vehicle-truck-red.glb" id="11_wocnk"] -[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tfk12"] -transparency = 1 -depth_draw_mode = 2 -shading_mode = 0 -vertex_color_use_as_albedo = true -albedo_texture = ExtResource("4_h8cj5") -disable_receive_shadows = true -billboard_mode = 3 -billboard_keep_scale = true -particles_anim_h_frames = 1 -particles_anim_v_frames = 1 -particles_anim_loop = false -grow_amount = 0.5 -proximity_fade_enabled = true -proximity_fade_distance = 0.25 - -[sub_resource type="Curve" id="Curve_t02a3"] -_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.503968, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] -point_count = 3 - -[sub_resource type="CurveTexture" id="CurveTexture_mya1o"] -curve = SubResource("Curve_t02a3") - -[sub_resource type="Curve" id="Curve_bncg7"] -_data = [Vector2(0, 0.5), 0.0, 0.0, 0, 0, Vector2(0.5, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.2), 0.5, 0.0, 0, 0] -point_count = 3 - -[sub_resource type="CurveTexture" id="CurveTexture_5pp1o"] -curve = SubResource("Curve_bncg7") - -[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_xgt35"] -angle_min = -90.0 -angle_max = 90.0 -gravity = Vector3(0, 0, 0) -damping_min = 1.0 -damping_max = 1.0 -scale_min = 0.25 -scale_max = 0.5 -scale_curve = SubResource("CurveTexture_5pp1o") -color = Color(0.3696, 0.3738, 0.42, 1) -alpha_curve = SubResource("CurveTexture_mya1o") - -[sub_resource type="QuadMesh" id="QuadMesh_68fxn"] - -[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_eyo0u"] -friction = 5.0 -rough = true - -[sub_resource type="SphereShape3D" id="SphereShape3D_hhncp"] - [sub_resource type="PhysicsMaterial" id="PhysicsMaterial_tipki"] friction = 0.0 bounce = 0.1 @@ -71,73 +17,18 @@ bounce = 0.1 [node name="Environment" type="WorldEnvironment" parent="."] environment = ExtResource("1_q4t1r") -[node name="Vehicle" type="Node3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.5, 0, 5) -script = ExtResource("2_xjb8m") - -[node name="Ground" type="RayCast3D" parent="Vehicle"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) -target_position = Vector3(0, -0.7, 0) -hit_back_faces = false -debug_shape_custom_color = Color(0.898039, 0, 0, 1) - -[node name="Container" type="Node3D" parent="Vehicle"] - -[node name="Model" parent="Vehicle/Container" instance=ExtResource("4_ya4ey")] - -[node name="TrailLeft" type="GPUParticles3D" parent="Vehicle/Container"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.05, -0.35) -material_override = SubResource("StandardMaterial3D_tfk12") -cast_shadow = 0 -amount = 32 -lifetime = 0.5 -fixed_fps = 60 -process_material = SubResource("ParticleProcessMaterial_xgt35") -draw_pass_1 = SubResource("QuadMesh_68fxn") - -[node name="TrailRight" type="GPUParticles3D" parent="Vehicle/Container"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0.05, -0.35) -material_override = SubResource("StandardMaterial3D_tfk12") -cast_shadow = 0 -amount = 32 -lifetime = 0.5 -fixed_fps = 60 -process_material = SubResource("ParticleProcessMaterial_xgt35") -draw_pass_1 = SubResource("QuadMesh_68fxn") - -[node name="ScreechSound" type="AudioStreamPlayer3D" parent="Vehicle/Container"] -stream = ExtResource("5_choun") -autoplay = true - -[node name="EngineSound" type="AudioStreamPlayer3D" parent="Vehicle/Container"] -stream = ExtResource("6_choun") -autoplay = true - -[node name="Sphere" type="RigidBody3D" parent="Vehicle"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) -collision_layer = 8 -mass = 1000.0 -physics_material_override = SubResource("PhysicsMaterial_eyo0u") -gravity_scale = 1.5 -continuous_cd = true -contact_monitor = true -max_contacts_reported = 1 -linear_damp = 0.1 -angular_damp_mode = 1 -angular_damp = 4.0 - -[node name="CollisionShape" type="CollisionShape3D" parent="Vehicle/Sphere"] -shape = SubResource("SphereShape3D_hhncp") - [node name="Plane" type="CSGBox3D" parent="."] transparency = 1.0 use_collision = true size = Vector3(60, 0, 60) +[node name="Vehicle" parent="." instance=ExtResource("2_o6xl0")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.5, 0, 5) + [node name="View" type="Node3D" parent="." node_paths=PackedStringArray("target")] transform = Transform3D(0.707107, -0.40558, 0.579228, 0, 0.819152, 0.573576, -0.707107, -0.40558, 0.579228, 3.5, 0, 5) script = ExtResource("5_0lrhn") -target = NodePath("../Vehicle/Container") +target = NodePath("../Vehicle") [node name="Camera" type="Camera3D" parent="View"] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 16) diff --git a/scenes/vehicle.tscn b/scenes/vehicle.tscn new file mode 100644 index 0000000..4ff7e4f --- /dev/null +++ b/scenes/vehicle.tscn @@ -0,0 +1,128 @@ +[gd_scene load_steps=15 format=3 uid="uid://badoy1c127yhf"] + +[ext_resource type="Script" uid="uid://bqite16pastgo" path="res://scripts/vehicle.gd" id="1_6gcpt"] +[ext_resource type="PackedScene" uid="uid://bynb5jk1d478y" path="res://models/vehicle-truck-yellow.glb" id="2_e2g1l"] +[ext_resource type="Texture2D" uid="uid://c026qrhqxgw3n" path="res://sprites/smoke.png" id="3_vuxys"] +[ext_resource type="AudioStream" uid="uid://2in1jtv5bh0y" path="res://audio/skid.ogg" id="4_p2hth"] +[ext_resource type="AudioStream" uid="uid://j6x2is8pyt8y" path="res://audio/engine.ogg" id="5_mcce1"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tfk12"] +transparency = 1 +depth_draw_mode = 2 +shading_mode = 0 +vertex_color_use_as_albedo = true +albedo_texture = ExtResource("3_vuxys") +disable_receive_shadows = true +billboard_mode = 3 +billboard_keep_scale = true +particles_anim_h_frames = 1 +particles_anim_v_frames = 1 +particles_anim_loop = false +grow_amount = 0.5 +proximity_fade_enabled = true +proximity_fade_distance = 0.25 + +[sub_resource type="Curve" id="Curve_t02a3"] +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.503968, 1), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_mya1o"] +curve = SubResource("Curve_t02a3") + +[sub_resource type="Curve" id="Curve_bncg7"] +_data = [Vector2(0, 0.5), 0.0, 0.0, 0, 0, Vector2(0.5, 1), 0.0, 0.0, 0, 0, Vector2(1, 0.2), 0.5, 0.0, 0, 0] +point_count = 3 + +[sub_resource type="CurveTexture" id="CurveTexture_5pp1o"] +curve = SubResource("Curve_bncg7") + +[sub_resource type="ParticleProcessMaterial" id="ParticleProcessMaterial_xgt35"] +angle_min = -90.0 +angle_max = 90.0 +gravity = Vector3(0, 0, 0) +damping_min = 1.0 +damping_max = 1.0 +scale_min = 0.25 +scale_max = 0.5 +scale_curve = SubResource("CurveTexture_5pp1o") +color = Color(0.3696, 0.3738, 0.42, 1) +alpha_curve = SubResource("CurveTexture_mya1o") + +[sub_resource type="QuadMesh" id="QuadMesh_68fxn"] + +[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_eyo0u"] +friction = 5.0 +rough = true + +[sub_resource type="SphereShape3D" id="SphereShape3D_hhncp"] + +[node name="Vehicle" type="Node3D" node_paths=PackedStringArray("sphere", "raycast", "vehicle_model", "vehicle_body", "wheel_fl", "wheel_fr", "wheel_bl", "wheel_br", "trail_left", "trail_right", "screech_sound", "engine_sound")] +script = ExtResource("1_6gcpt") +sphere = NodePath("Sphere") +raycast = NodePath("Ground") +vehicle_model = NodePath("Container") +vehicle_body = NodePath("Container/Model/body") +wheel_fl = NodePath("Container/Model/wheel-front-left") +wheel_fr = NodePath("Container/Model/wheel-front-right") +wheel_bl = NodePath("Container/Model/wheel-back-left") +wheel_br = NodePath("Container/Model/wheel-back-right") +trail_left = NodePath("Container/TrailLeft") +trail_right = NodePath("Container/TrailRight") +screech_sound = NodePath("Container/ScreechSound") +engine_sound = NodePath("Container/EngineSound") + +[node name="Ground" type="RayCast3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +target_position = Vector3(0, -0.7, 0) +hit_back_faces = false +debug_shape_custom_color = Color(0.898039, 0, 0, 1) + +[node name="Container" type="Node3D" parent="."] + +[node name="Model" parent="Container" instance=ExtResource("2_e2g1l")] + +[node name="TrailLeft" type="GPUParticles3D" parent="Container"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.25, 0.05, -0.35) +material_override = SubResource("StandardMaterial3D_tfk12") +cast_shadow = 0 +amount = 32 +lifetime = 0.5 +fixed_fps = 60 +process_material = SubResource("ParticleProcessMaterial_xgt35") +draw_pass_1 = SubResource("QuadMesh_68fxn") + +[node name="TrailRight" type="GPUParticles3D" parent="Container"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.25, 0.05, -0.35) +material_override = SubResource("StandardMaterial3D_tfk12") +cast_shadow = 0 +amount = 32 +lifetime = 0.5 +fixed_fps = 60 +process_material = SubResource("ParticleProcessMaterial_xgt35") +draw_pass_1 = SubResource("QuadMesh_68fxn") + +[node name="ScreechSound" type="AudioStreamPlayer3D" parent="Container"] +stream = ExtResource("4_p2hth") +autoplay = true + +[node name="EngineSound" type="AudioStreamPlayer3D" parent="Container"] +stream = ExtResource("5_mcce1") +autoplay = true + +[node name="Sphere" type="RigidBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0) +collision_layer = 8 +mass = 1000.0 +physics_material_override = SubResource("PhysicsMaterial_eyo0u") +gravity_scale = 1.5 +continuous_cd = true +contact_monitor = true +max_contacts_reported = 1 +linear_damp = 0.1 +angular_damp_mode = 1 +angular_damp = 4.0 + +[node name="CollisionShape" type="CollisionShape3D" parent="Sphere"] +shape = SubResource("SphereShape3D_hhncp") + +[editable path="Container/Model"] diff --git a/scripts/vehicle.gd b/scripts/vehicle.gd index bdb7c82..8629b15 100644 --- a/scripts/vehicle.gd +++ b/scripts/vehicle.gd @@ -1,29 +1,28 @@ -extends Node3D +class_name Vehicle extends Node3D -# Nodes +@export_category("Nodes") +@export var sphere: RigidBody3D +@export var raycast: RayCast3D -@onready var sphere: RigidBody3D = $Sphere -@onready var raycast: RayCast3D = $Ground +@export_category("Vehicle Elements") +@export var vehicle_model: Node3D +@export var vehicle_body: Node3D -# Vehicle elements +@export_group("Wheels") +@export var wheel_fl: MeshInstance3D +@export var wheel_fr: MeshInstance3D +@export var wheel_bl: MeshInstance3D +@export var wheel_br: MeshInstance3D -@onready var vehicle_model = $Container -@onready var vehicle_body = $Container/Model/body +@export_category("FX") +@export_group("Particles") +@export var trail_left: GPUParticles3D +@export var trail_right: GPUParticles3D -@onready var wheel_fl = $"Container/Model/wheel-front-left" -@onready var wheel_fr = $"Container/Model/wheel-front-right" -@onready var wheel_bl = $"Container/Model/wheel-back-left" -@onready var wheel_br = $"Container/Model/wheel-back-right" +@export_group("Audio") +@export var screech_sound: AudioStreamPlayer3D +@export var engine_sound: AudioStreamPlayer3D -# Effects - -@onready var trail_left: GPUParticles3D = $Container/TrailLeft -@onready var trail_right: GPUParticles3D = $Container/TrailRight - -# Sounds - -@onready var screech_sound: AudioStreamPlayer3D = $Container/ScreechSound -@onready var engine_sound: AudioStreamPlayer3D = $Container/EngineSound var input: Vector3 var normal: Vector3 @@ -34,11 +33,16 @@ var linear_speed: float var colliding: bool -# Functions +# Public Functions + +func get_vehicle_pos() -> Vector3: + return vehicle_model.global_position + +# Private Functions func _physics_process(delta): - handle_input(delta) + _handle_input(delta) var direction = sign(linear_speed) if direction == 0: direction = sign(input.z) if abs(input.z) > 0.1 else 1 @@ -62,7 +66,7 @@ func _physics_process(delta): # Orient model to colliding normal if normal.dot(vehicle_model.global_basis.y) > 0.5: - var xform = align_with_y(vehicle_model.global_transform, normal) + var xform = _align_with_y(vehicle_model.global_transform, normal) vehicle_model.global_transform = vehicle_model.global_transform.interpolate_with(xform, 0.2).orthonormalized() colliding = raycast.is_colliding() @@ -86,14 +90,14 @@ func _physics_process(delta): # Visual and audio effects - effect_engine(delta) - effect_body(delta) - effect_wheels(delta) - effect_trails() + _effect_engine(delta) + _effect_body(delta) + _effect_wheels(delta) + _effect_trails() # Handle input when vehicle is colliding with ground -func handle_input(delta): +func _handle_input(delta): if raycast.is_colliding(): input.x = Input.get_axis("left", "right") @@ -101,7 +105,7 @@ func handle_input(delta): sphere.angular_velocity += vehicle_model.get_global_transform().basis.x * (linear_speed * 100) * delta -func effect_body(delta): +func _effect_body(delta): # Slightly tilt body based on acceleration and steering @@ -112,7 +116,9 @@ func effect_body(delta): vehicle_body.position = vehicle_body.position.lerp(Vector3(0, 0.2, 0), delta * 5) -func effect_wheels(delta): +# Spin and rotate wheels (based on direction) + +func _effect_wheels(delta): # Rotate wheels based on acceleration @@ -126,7 +132,7 @@ func effect_wheels(delta): # Engine sounds -func effect_engine(delta): +func _effect_engine(delta): var speed_factor = clamp(abs(linear_speed), 0.0, 1.0) var throttle_factor = clamp(abs(input.z), 0.0, 1.0) @@ -141,7 +147,7 @@ func effect_engine(delta): # Show trails (and play skid sound) -func effect_trails(): +func _effect_trails(): var drift_intensity = abs(linear_speed - acceleration) + (abs(vehicle_body.rotation.z) * 2.0) var should_emit = drift_intensity > 0.25 @@ -157,7 +163,7 @@ func effect_trails(): # Align vehicle with normal -func align_with_y(xform, new_y): +func _align_with_y(xform, new_y): xform.basis.y = new_y xform.basis.x = -xform.basis.z.cross(new_y) diff --git a/scripts/view.gd b/scripts/view.gd index d581a51..5fcbd5e 100644 --- a/scripts/view.gd +++ b/scripts/view.gd @@ -1,9 +1,8 @@ extends Node3D @export_group("Properties") -@export var target: Node +@export var target: Vehicle -@onready var camera = $Camera # Functions @@ -11,4 +10,4 @@ func _physics_process(delta): # Set position and rotation to targets - self.position = self.position.lerp(target.global_position, delta * 4) + self.position = self.position.lerp(target.get_vehicle_pos(), delta * 4)