small racing game im working on
| -rw-r--r-- | assets/cars/kenney_sedan/sedan.tscn | 6 | ||||
| -rw-r--r-- | cam.gd | 33 | ||||
| -rw-r--r-- | classes/car.gd | 15 | ||||
| -rw-r--r-- | classes/checkpoint.gd | 7 | ||||
| -rw-r--r-- | classes/finish.gd | 11 | ||||
| -rw-r--r-- | race.gd | 29 | ||||
| -rw-r--r-- | race.tscn | 174 | ||||
| -rw-r--r-- | scenes/ring_checkpoint.gd | 6 | ||||
| -rw-r--r-- | scenes/ring_checkpoint.tscn | 14 | ||||
| -rw-r--r-- | scenes/ring_finish.gd | 4 | ||||
| -rw-r--r-- | scenes/ring_finish.tscn | 11 | ||||
| -rw-r--r-- | scenes/ring_start.tscn | 4 | ||||
| -rw-r--r-- | scenes/track-base.gd | 29 | ||||
| -rw-r--r-- | scenes/track.tscn | 4 | ||||
| -rw-r--r-- | tracks/test.tres | 18 | ||||
| -rw-r--r-- | ui/intro_cam.gd | 27 | ||||
| -rw-r--r-- | ui/map.gd | 13 | ||||
| -rw-r--r-- | ui/speedometer.gd | 11 |
18 files changed, 309 insertions, 107 deletions
diff --git a/assets/cars/kenney_sedan/sedan.tscn b/assets/cars/kenney_sedan/sedan.tscn index f7d01c9..e3643e1 100644 --- a/assets/cars/kenney_sedan/sedan.tscn +++ b/assets/cars/kenney_sedan/sedan.tscn @@ -1,6 +1,5 @@ -[gd_scene load_steps=21 format=3 uid="uid://ccn1nk1a0b0sa"] +[gd_scene load_steps=20 format=3 uid="uid://ccn1nk1a0b0sa"] -[ext_resource type="Script" path="res://classes/human_car.gd" id="1_2rc1g"] [ext_resource type="PackedScene" uid="uid://bbj2agqv581cd" path="res://assets/cars/kenney_sedan/sedan.blend" id="1_a083g"] [ext_resource type="Material" uid="uid://b0t01t5nxdfdp" path="res://assets/cars/skid.tres" id="3_abyal"] [ext_resource type="SphereMesh" uid="uid://cd2plk55q0xr7" path="res://assets/cars/sphere.tres" id="4_nipof"] @@ -295,7 +294,6 @@ radial_segments = 16 rings = 12 [node name="Sedan" type="Node3D"] -script = ExtResource("1_2rc1g") [node name="CarMesh" parent="." instance=ExtResource("1_a083g")] @@ -340,10 +338,8 @@ draw_pass_1 = ExtResource("4_nipof") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) [node name="Ball" type="RigidBody3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2, 0.5) collision_layer = 2 collision_mask = 3 -axis_lock_angular_y = true physics_material_override = SubResource("PhysicsMaterial_grep7") linear_damp = 0.1 angular_damp = 5.0 @@ -1,20 +1,18 @@ extends Camera3D -@export var follow_this: Node3D +var follow_this: Node3D @export var target_distance = 3.0 @export var target_height = 2.0 var last_lookat func _ready(): - last_lookat = follow_this.global_transform.origin - if follow_this is Car: - await follow_this.ready - follow_this = follow_this.car_mesh + set_physics_process(false) -func _physics_process(delta): - var delta_v = global_transform.origin - follow_this.global_transform.origin - var target_pos = global_transform.origin + +func target() -> Vector3: + var delta_v := global_position - follow_this.global_position + var target_pos := global_position # ignore y delta_v.y = 0.0 @@ -22,12 +20,21 @@ func _physics_process(delta): if (delta_v.length() > target_distance): delta_v = delta_v.normalized() * target_distance delta_v.y = target_height - target_pos = follow_this.global_transform.origin + delta_v + target_pos = follow_this.global_position + delta_v else: - target_pos.y = follow_this.global_transform.origin.y + target_height - - global_transform.origin = global_transform.origin.lerp(target_pos, delta * 20.0) + target_pos.y = follow_this.global_position.y + target_height + return target_pos - last_lookat = last_lookat.lerp(follow_this.global_transform.origin, delta * 20.0) +func _physics_process(delta): + global_position = global_position.lerp(target(), delta * 20.0) + last_lookat = last_lookat.lerp(follow_this.global_position, delta * 20.0) look_at(last_lookat, Vector3(0.0, 1.0, 0.0)) + + +func _on_race_created_car(car: Car) -> void: + follow_this = car.car_mesh + global_position = follow_this.global_position + (follow_this.global_transform.basis.z * target_distance) + look_at(follow_this.global_position) + last_lookat = follow_this.global_position + set_physics_process(true) diff --git a/classes/car.gd b/classes/car.gd index 87fbab7..133abff 100644 --- a/classes/car.gd +++ b/classes/car.gd @@ -13,7 +13,7 @@ class_name Car @export var show_debug := false var acceleration := 35.0 # ai must change this for randomness -const sphere_offset := Vector3(0, -2, .5) +const sphere_offset := Vector3(0, -2.3, 0) const max_steering_range := deg_to_rad(40.0) const turn_speed := 2.0 const wheel_turn_speed := 0.2 @@ -37,10 +37,11 @@ func steer(to: float) -> void: func move_mesh(delta: float) -> void: # just lerp the y due to trimesh bouncing - car_mesh.transform.origin.x = ball.transform.origin.x + sphere_offset.x - car_mesh.transform.origin.z = ball.transform.origin.z + sphere_offset.z - car_mesh.transform.origin.y = lerp(car_mesh.transform.origin.y, ball.transform.origin.y + sphere_offset.y, 1 * delta) - ball.apply_central_force(-car_mesh.global_transform.basis.z * throttle) + car_mesh.global_position.x = ball.global_position.x + sphere_offset.x + car_mesh.global_position.z = ball.global_position.z + sphere_offset.z + car_mesh.global_position.y = lerp(car_mesh.global_position.y, ball.global_position.y + sphere_offset.y, 10 * delta) + if !ball.freeze: + ball.apply_central_force(-car_mesh.global_transform.basis.z * throttle) func turn(delta: float) -> void: if ball.linear_velocity.length() > turn_stop_limit: @@ -50,8 +51,8 @@ func turn(delta: float) -> void: # tilt body for effect body_mesh.rotation.z = lerp(body_mesh.rotation.z, clampf((-_steering * .2) * ball.linear_velocity.length_squared() / body_tilt, -.4, .4), 10 * delta) -func floor_mesh(delta: float) -> void: - var n = ground_ray.get_collision_normal() +func floor_mesh(delta: float) -> void: + var n := ground_ray.get_collision_normal() var xform := align_with_y(car_mesh.global_transform, n.normalized()) car_mesh.global_transform = car_mesh.global_transform.interpolate_with(xform, 10 * delta) diff --git a/classes/checkpoint.gd b/classes/checkpoint.gd index 47844c4..c0d7fc4 100644 --- a/classes/checkpoint.gd +++ b/classes/checkpoint.gd @@ -1,6 +1,11 @@ extends PathFollow3D class_name CheckPoint -signal player_entered +signal collected + +var id: int # checkpoint id @export var needs_collision := true + +func enter() -> void: + collected.emit()
\ No newline at end of file diff --git a/classes/finish.gd b/classes/finish.gd index a936380..d7c9eb9 100644 --- a/classes/finish.gd +++ b/classes/finish.gd @@ -1,2 +1,9 @@ -extends CheckPoint -class_name Finish
\ No newline at end of file +extends PathFollow3D +class_name Finish + +signal collected + +@export var needs_collision := true + +func enter() -> void: + collected.emit()
\ No newline at end of file @@ -1,9 +1,28 @@ extends Node3D -@export var car: Car +@export var car: PackedScene +@export var track: TrackLoader -func _on_track_place_car(at: Vector3, rot: Vector3) -> void: - # await car.ready - car.ball.global_position = at + (Vector3.UP * 2) - car.ball.global_rotation = rot +signal created_car(car: Car) +func _ready() -> void: + var c: Node3D = car.instantiate() + c.set_script(load("res://classes/human_car.gd")) + c.show_debug = true + add_child(c) + c.ball.freeze = true + c.visible = false + c.global_position = track.start_pos + Vector3.UP * 3.5 + c.set_deferred(&"rotation", track.start_rot + Vector3.UP * PI) + await get_tree().process_frame + c.global_position = c.global_position - (c.ball.global_transform.basis.z * 2) # bump forward a teensy bit + c.visible = true + created_car.emit(c) + for cp in track.checkpoints: + cp.collected.connect(collect.bind(cp.id)) + +func collect(cp: int) -> void: + print("collected cp %d" % cp) + collected_checkpoints.append(cp) + +var collected_checkpoints: PackedInt32Array = [] @@ -1,4 +1,4 @@ -[gd_scene load_steps=16 format=3 uid="uid://dmkcxlevx4c7g"] +[gd_scene load_steps=20 format=3 uid="uid://dmkcxlevx4c7g"] [ext_resource type="Script" path="res://race.gd" id="1_ckbwd"] [ext_resource type="Environment" uid="uid://biwshm46yl62v" path="res://default_env.tres" id="2_pnp7e"] @@ -13,6 +13,7 @@ [ext_resource type="PackedScene" uid="uid://clw61td2wh84w" path="res://scenes/track.tscn" id="11_6q53c"] [ext_resource type="Curve3D" uid="uid://cuonflkcdybj0" path="res://tracks/test_curve.tres" id="12_8yl7p"] [ext_resource type="Resource" uid="uid://de46bcu1ivmtq" path="res://tracks/test.tres" id="13_sh6e8"] +[ext_resource type="Script" path="res://ui/intro_cam.gd" id="14_yajvg"] [sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_tkhh8"] @@ -20,9 +21,114 @@ material = ExtResource("4_i1mlf") size = Vector2(5000, 5000) -[node name="race" type="Node3D" node_paths=PackedStringArray("car")] +[sub_resource type="Animation" id="Animation_uaks0"] +resource_name = "count_in" +length = 1.5 +step = 0.5 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Counter:text") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.5, 1, 1.5), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": ["[center][b]3[/b][/center]", "[center][b]2[/b][/center] +", "[center][b]1[/b][/center] +", ""] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Counter:theme_override_colors/default_color") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 1.5), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Color(1, 0.360784, 0.227451, 1), Color(0.980392, 0.737255, 0, 1)] +} +tracks/2/type = "method" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("CanvasLayer/HBoxContainer/Panel2/Timer") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(1.5), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"start" +}] +} +tracks/3/type = "method" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Counter") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(), +"transitions": PackedFloat32Array(), +"values": [] +} +tracks/4/type = "method" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Camera") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(1.5), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"make_current" +}] +} + +[sub_resource type="Animation" id="Animation_2si4r"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Counter:text") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [" +"] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_hplnw"] +_data = { +"RESET": SubResource("Animation_2si4r"), +"count_in": SubResource("Animation_uaks0") +} + +[node name="race" type="Node3D" node_paths=PackedStringArray("track")] script = ExtResource("1_ckbwd") -car = NodePath("Sedan") +car = ExtResource("6_nu32e") +track = NodePath("Track") + +[node name="Track" parent="." instance=ExtResource("11_6q53c")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) +curve = ExtResource("12_8yl7p") +track = ExtResource("13_sh6e8") + +[node name="Camera" type="Camera3D" parent="."] +transform = Transform3D(0.226651, 0, -0.973976, 0, 1, 0, 0.973976, 0, 0.226651, -25.1963, 1.82268, -2.33777) +far = 500.0 +script = ExtResource("5_nb035") +target_distance = 9.0 +target_height = 4.0 [node name="Env" type="WorldEnvironment" parent="."] environment = ExtResource("2_pnp7e") @@ -38,16 +144,6 @@ shape = SubResource("WorldBoundaryShape3D_tkhh8") [node name="MeshInstance" type="MeshInstance3D" parent="Ground"] mesh = SubResource("PlaneMesh_ta0cd") -[node name="Camera3D" type="Camera3D" parent="." node_paths=PackedStringArray("follow_this")] -far = 500.0 -script = ExtResource("5_nb035") -follow_this = NodePath("../Sedan") -target_distance = 9.0 -target_height = 5.0 - -[node name="Sedan" parent="." instance=ExtResource("6_nu32e")] -transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 2, 100) - [node name="CanvasLayer" type="CanvasLayer" parent="."] [node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer"] @@ -65,7 +161,7 @@ alignment = 1 [node name="Panel" type="PanelContainer" parent="CanvasLayer/HBoxContainer"] layout_mode = 2 -[node name="Speedometer" type="Label" parent="CanvasLayer/HBoxContainer/Panel" node_paths=PackedStringArray("car")] +[node name="Speedometer" type="Label" parent="CanvasLayer/HBoxContainer/Panel"] custom_minimum_size = Vector2(0, 105) layout_mode = 2 size_flags_horizontal = 4 @@ -73,7 +169,6 @@ text = "龍 0km/h" horizontal_alignment = 1 vertical_alignment = 1 script = ExtResource("8_awr5n") -car = NodePath("../../../../Sedan") [node name="Panel2" type="PanelContainer" parent="CanvasLayer/HBoxContainer"] layout_mode = 2 @@ -87,19 +182,52 @@ horizontal_alignment = 1 vertical_alignment = 1 script = ExtResource("9_dn61b") -[node name="MiniMap" type="Line2D" parent="CanvasLayer" node_paths=PackedStringArray("track", "car")] +[node name="MiniMap" type="Line2D" parent="CanvasLayer" node_paths=PackedStringArray("track")] position = Vector2(300, 145) default_color = Color(0.588235, 0.588235, 0.588235, 0.537255) joint_mode = 2 antialiased = true script = ExtResource("10_58kgt") track = NodePath("../../Track") -car = NodePath("../../Sedan") player_color = Color(1, 0.388235, 0.321569, 0.803922) -[node name="Track" parent="." instance=ExtResource("11_6q53c")] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) -curve = ExtResource("12_8yl7p") -track = ExtResource("13_sh6e8") - -[connection signal="place_car" from="Track" to="." method="_on_track_place_car"] +[node name="IntroCamera" type="Camera3D" parent="." node_paths=PackedStringArray("main_cam", "track", "count_player")] +transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0, 0, 0) +current = true +far = 500.0 +script = ExtResource("14_yajvg") +main_cam = NodePath("../Camera") +track = NodePath("../Track") +count_player = NodePath("../CountPlayer") + +[node name="Counter" type="RichTextLabel" parent="."] +custom_minimum_size = Vector2(1400, 0) +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -20.0 +offset_top = -20.0 +offset_right = 20.0 +offset_bottom = 20.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_colors/default_color = Color(0.980392, 0.737255, 0, 1) +theme_override_colors/font_outline_color = Color(0, 0, 0, 1) +theme_override_constants/outline_size = 50 +theme_override_font_sizes/bold_font_size = 800 +bbcode_enabled = true +text = " +" +fit_content = true + +[node name="CountPlayer" type="AnimationPlayer" parent="."] +libraries = { +"": SubResource("AnimationLibrary_hplnw") +} + +[connection signal="created_car" from="." to="Camera" method="_on_race_created_car"] +[connection signal="created_car" from="." to="CanvasLayer/HBoxContainer/Panel/Speedometer" method="_on_race_created_car"] +[connection signal="created_car" from="." to="CanvasLayer/MiniMap" method="_on_race_created_car"] +[connection signal="created_car" from="." to="IntroCamera" method="_on_race_created_car"] diff --git a/scenes/ring_checkpoint.gd b/scenes/ring_checkpoint.gd index 07443f4..7f67fc9 100644 --- a/scenes/ring_checkpoint.gd +++ b/scenes/ring_checkpoint.gd @@ -2,8 +2,4 @@ extends CheckPoint func _ready() -> void: if not needs_collision: - $Ring/Collision.queue_free() - -func _on_player_entered(_body: Node3D) -> void: - print("player entered!") - player_entered.emit() + $Ring/Collision.queue_free()
\ No newline at end of file diff --git a/scenes/ring_checkpoint.tscn b/scenes/ring_checkpoint.tscn index 315c8d7..eae51f3 100644 --- a/scenes/ring_checkpoint.tscn +++ b/scenes/ring_checkpoint.tscn @@ -1,20 +1,20 @@ [gd_scene load_steps=5 format=3 uid="uid://d4a3e1w62m3ck"] -[ext_resource type="Script" path="res://classes/checkpoint.gd" id="1_kak2a"] +[ext_resource type="Script" path="res://scenes/ring_checkpoint.gd" id="1_cmmpp"] [ext_resource type="TorusMesh" uid="uid://dlbpusye3e33p" path="res://assets/meshes/checkpoint.tres" id="2_xys6y"] -[sub_resource type="TorusMesh" id="TorusMesh_nyq70"] +[sub_resource type="TorusMesh" id="TorusMesh_wt6vi"] inner_radius = 25.0 outer_radius = 40.0 rings = 10 ring_segments = 4 -[sub_resource type="BoxShape3D" id="BoxShape3D_0mg7y"] +[sub_resource type="BoxShape3D" id="BoxShape3D_2btqs"] size = Vector3(52, 52, 3) [node name="Checkpoint" type="PathFollow3D"] transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 0, 0) -script = ExtResource("1_kak2a") +script = ExtResource("1_cmmpp") [node name="Ring" type="MeshInstance3D" parent="."] transform = Transform3D(1, 0, 0, 0, -4.37114e-08, -1, 0, 1, -4.37114e-08, 0, 0, 0) @@ -24,7 +24,7 @@ mesh = ExtResource("2_xys6y") transform = Transform3D(1, 0, 0, 0, 1, -8.35187e-23, 0, -8.35187e-23, 1, 0, 0, 0) visible = false use_collision = true -mesh = SubResource("TorusMesh_nyq70") +mesh = SubResource("TorusMesh_wt6vi") [node name="PlayerDetector" type="Area3D" parent="."] collision_layer = 0 @@ -32,6 +32,6 @@ collision_mask = 2 monitorable = false [node name="Area" type="CollisionShape3D" parent="PlayerDetector"] -shape = SubResource("BoxShape3D_0mg7y") +shape = SubResource("BoxShape3D_2btqs") -[connection signal="body_entered" from="PlayerDetector" to="." method="_on_player_entered"] +[connection signal="body_entered" from="PlayerDetector" to="." method="enter" flags=6 unbinds=1] diff --git a/scenes/ring_finish.gd b/scenes/ring_finish.gd index ce7501e..05e36aa 100644 --- a/scenes/ring_finish.gd +++ b/scenes/ring_finish.gd @@ -3,7 +3,3 @@ extends Finish func _ready() -> void: if not needs_collision: $Ring/Collision.queue_free() - -func _on_player_entered(_body: Node3D) -> void: - print("player finished!") - player_entered.emit() diff --git a/scenes/ring_finish.tscn b/scenes/ring_finish.tscn index 7e9f7d0..1c3a86e 100644 --- a/scenes/ring_finish.tscn +++ b/scenes/ring_finish.tscn @@ -3,13 +3,13 @@ [ext_resource type="Script" path="res://scenes/ring_finish.gd" id="1_oj823"] [ext_resource type="TorusMesh" uid="uid://bc8hyk8kfo4q1" path="res://assets/meshes/ring_finish.tres" id="2_hvrqd"] -[sub_resource type="TorusMesh" id="TorusMesh_oms0g"] +[sub_resource type="TorusMesh" id="TorusMesh_c1qmt"] inner_radius = 25.0 outer_radius = 40.0 rings = 10 ring_segments = 4 -[sub_resource type="BoxShape3D" id="BoxShape3D_ue5ee"] +[sub_resource type="BoxShape3D" id="BoxShape3D_431ml"] size = Vector3(52, 52, 3) [node name="RingFinish" type="PathFollow3D"] @@ -23,12 +23,15 @@ mesh = ExtResource("2_hvrqd") transform = Transform3D(1, 0, 0, 0, 1, -8.35187e-23, 0, -8.35187e-23, 1, 0, 0, 0) visible = false use_collision = true -mesh = SubResource("TorusMesh_oms0g") +mesh = SubResource("TorusMesh_c1qmt") [node name="PlayerDetector" type="Area3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.34943, 1.90735e-06, 0.0562134) collision_layer = 0 collision_mask = 2 monitorable = false [node name="Area" type="CollisionShape3D" parent="PlayerDetector"] -shape = SubResource("BoxShape3D_ue5ee") +shape = SubResource("BoxShape3D_431ml") + +[connection signal="body_entered" from="PlayerDetector" to="." method="enter" flags=6 unbinds=1] diff --git a/scenes/ring_start.tscn b/scenes/ring_start.tscn index 0135c28..6320c32 100644 --- a/scenes/ring_start.tscn +++ b/scenes/ring_start.tscn @@ -3,7 +3,7 @@ [ext_resource type="TorusMesh" uid="uid://cwiqggu3nwbyh" path="res://assets/meshes/ring_start.tres" id="1_ksild"] [ext_resource type="Script" path="res://scenes/ring_start.gd" id="1_kvj6d"] -[sub_resource type="TorusMesh" id="TorusMesh_24cjh"] +[sub_resource type="TorusMesh" id="TorusMesh_e4fn4"] inner_radius = 25.0 outer_radius = 40.0 rings = 10 @@ -20,4 +20,4 @@ mesh = ExtResource("1_ksild") transform = Transform3D(1, 0, 0, 0, 1, -8.35187e-23, 0, -8.35187e-23, 1, 0, 0, 0) visible = false use_collision = true -mesh = SubResource("TorusMesh_24cjh") +mesh = SubResource("TorusMesh_e4fn4") diff --git a/scenes/track-base.gd b/scenes/track-base.gd index ab034e8..ea2f40d 100644 --- a/scenes/track-base.gd +++ b/scenes/track-base.gd @@ -23,13 +23,14 @@ class_name TrackLoader @onready var collision := $CollisionShape as CSGPolygon3D @onready var sun := $Sun as DirectionalLight3D -signal place_car(at: Vector3, rot: Vector3) +var checkpoints: Array[CheckPoint] +var start_rot: Vector3 +var start_pos: Vector3 var is_dirty := true func vec(x := 0.0, y := 0.0) -> Vector2: return Vector2(x, y) - func _update(): if !is_dirty or !track or !track.track: # curve = null # editor freezes with this, idk why @@ -100,18 +101,20 @@ func _update(): if child is PathFollow3D: child.queue_free() - for cp in track.checkpoints: - var _c: CheckPoint = make_follower(track.checkpoint_scene, cp, track.checkpoint_scale, track.checkpoint_needs_collision) + for i in len(track.checkpoints): + var c: CheckPoint = make_follower(track.checkpoint_scene, track.checkpoints[i], track.checkpoint_scale, track.checkpoint_needs_collision) + checkpoints.append(c) + if not Engine.is_editor_hint(): # godot tools are wierd + c.id = i var f: Finish = make_follower(track.finish_scene, track.finish_location, track.finish_scale, track.finish_needs_collision) - var start_position := f.global_position - var start_rot := f.global_rotation + start_pos = f.global_position + start_rot = f.rotation if track.laps == 0: var s: Start = make_follower(track.start_scene, track.start_location, track.start_scale, track.start_needs_collision) - start_position = s.global_position - start_rot = s.global_rotation - if not Engine.is_editor_hint(): - place_car.emit(start_position, start_rot) + start_pos = s.global_position + start_rot = s.rotation + start_rot = start_rot.snapped(Vector3(PI/2, PI/2, PI/2)) # loopage rail_l.path_joined = track.is_loop @@ -123,16 +126,16 @@ func _update(): is_dirty = false func _ready(): - call_deferred("_update") + _update() func _on_curve_changed() -> void: is_dirty = true call_deferred("_update") -func make_follower(scene: PackedScene, ratio: float, scl: Vector3, collision: bool) -> PathFollow3D: +func make_follower(scene: PackedScene, ratio: float, scl: Vector3, collide: bool) -> PathFollow3D: var follower: PathFollow3D = scene.instantiate() + follower.needs_collision = collide add_child(follower) follower.scale = scl - follower.needs_collision = collision follower.progress_ratio = ratio # ratio set must be after add_child() return follower
\ No newline at end of file diff --git a/scenes/track.tscn b/scenes/track.tscn index 5f5ace8..074ce0b 100644 --- a/scenes/track.tscn +++ b/scenes/track.tscn @@ -32,7 +32,7 @@ mode = 2 path_node = NodePath("..") path_interval_type = 0 path_interval = 1.0 -path_simplify_angle = 10.0 +path_simplify_angle = 3.0 path_rotation = 2 path_local = false path_continuous_u = true @@ -72,7 +72,7 @@ mode = 2 path_node = NodePath("..") path_interval_type = 0 path_interval = 1.0 -path_simplify_angle = 5.0 +path_simplify_angle = 3.0 path_rotation = 2 path_local = false path_continuous_u = true diff --git a/tracks/test.tres b/tracks/test.tres index f4ca576..2f1ff99 100644 --- a/tracks/test.tres +++ b/tracks/test.tres @@ -8,10 +8,10 @@ [resource] script = ExtResource("3_o0ql2") -track_width = 17.0 +track_width = 15.0 rail_distance = 3.0 -lower_support_width = 15.0 -support_height = 8.0 +lower_support_width = 23.0 +support_height = 12.0 track = ExtResource("5_35ahq") left_barrier = true right_barrier = true @@ -22,13 +22,13 @@ offset = Vector3(0, 1, 0) laps = 0 checkpoints = PackedFloat32Array(0.5) checkpoint_scene = ExtResource("1_ra7ed") -checkpoint_scale = Vector3(0.3, 0.3, 0.3) -checkpoint_needs_collision = false +checkpoint_scale = Vector3(0.4, 0.4, 0.4) +checkpoint_needs_collision = true finish_location = 1.0 finish_scene = ExtResource("2_e22em") -finish_scale = Vector3(0.3, 0.3, 0.3) -finish_needs_collision = false +finish_scale = Vector3(0.4, 0.4, 0.4) +finish_needs_collision = true start_location = 0.0 start_scene = ExtResource("4_8biam") -start_scale = Vector3(0.3, 0.3, 0.3) -start_needs_collision = false +start_scale = Vector3(0.4, 0.4, 0.4) +start_needs_collision = true diff --git a/ui/intro_cam.gd b/ui/intro_cam.gd new file mode 100644 index 0000000..00c2afe --- /dev/null +++ b/ui/intro_cam.gd @@ -0,0 +1,27 @@ +extends Camera3D + +@export var main_cam: Camera3D +@export var track: TrackLoader +@export var count_player: AnimationPlayer + +var car: Car + +func _ready() -> void: + var box := AABB() + for point in track.track.track.get_baked_points(): + box = box.expand(point) + box = box.grow(200) + var box_center := box.get_center() + var top_center := Vector3(box_center.x, -box.position.y, box_center.z) + global_position = top_center + await get_tree().create_timer(2).timeout + var tween := get_tree().create_tween().set_trans(Tween.TRANS_SINE).set_ease(Tween.EASE_IN_OUT) + tween.tween_property(self, ^"global_position", main_cam.global_position, 2) + tween.tween_property(self, ^"global_rotation", main_cam.global_rotation, 1) + await tween.finished + count_player.play(&"count_in") + await count_player.animation_finished + car.ball.freeze = false + +func _on_race_created_car(_car: Car) -> void: + car = _car @@ -1,10 +1,12 @@ extends Line2D +class_name MiniMap +var car: Node3D @export var track: TrackLoader -@export var car: Node3D @export var player_color: Color func _ready() -> void: + set_process(false) clear_points() width = track.track.track_width if !track.track.is_loop: @@ -14,13 +16,18 @@ func _ready() -> void: var p := flatten(point_3d) add_point(p) - func _process(_delta: float) -> void: queue_redraw() func _draw() -> void: - var point := flatten(track.curve.get_closest_point(car.ball.global_position)) + if !car: return + var point := flatten(track.curve.get_closest_point(car.global_position)) draw_circle(point, width / 2, player_color) func flatten(vec: Vector3) -> Vector2: return Vector2(vec.x, vec.z) + +func _on_race_created_car(_car) -> void: + car = _car.ball + set_process(true) + diff --git a/ui/speedometer.gd b/ui/speedometer.gd index 39ec8ca..c9eb0c9 100644 --- a/ui/speedometer.gd +++ b/ui/speedometer.gd @@ -1,7 +1,14 @@ extends Label @export var f_string = "龍 %dkm/h" -@export var car: Node3D +var car: Node3D + +func _ready() -> void: + set_process(false) func _process(_delta: float) -> void: - text = f_string % (car.ball.linear_velocity.length_squared() / 12) + text = f_string % (car.linear_velocity.length_squared() / 12) + +func _on_race_created_car(_car: Car) -> void: + car = _car.ball + set_process(true) |