enhancing car behavior
This commit is contained in:
parent
582b2c43cb
commit
aef117bcf9
@ -12,3 +12,11 @@
|
|||||||
- `test1/test1` - Super User
|
- `test1/test1` - Super User
|
||||||
- `test3/test3` - User
|
- `test3/test3` - User
|
||||||
|
|
||||||
|
## Controls
|
||||||
|
- Move: WASD
|
||||||
|
- Jump: Space
|
||||||
|
- Interact (enter/exit car): E
|
||||||
|
- Flashlight: F
|
||||||
|
- Phone: Tab
|
||||||
|
- Pause menu: Esc
|
||||||
|
|
||||||
|
|||||||
@ -5,6 +5,7 @@ extends Node3D
|
|||||||
@export var camera_path: NodePath
|
@export var camera_path: NodePath
|
||||||
@export var look_origin_path: NodePath = NodePath("Body/HeadPivot")
|
@export var look_origin_path: NodePath = NodePath("Body/HeadPivot")
|
||||||
@export var look_reference_path: NodePath = NodePath("Body")
|
@export var look_reference_path: NodePath = NodePath("Body")
|
||||||
|
@export var look_target_path: NodePath = NodePath("")
|
||||||
@export var lock_vertical: bool = true
|
@export var lock_vertical: bool = true
|
||||||
@export var vertical_unlock_height: float = 0.6
|
@export var vertical_unlock_height: float = 0.6
|
||||||
@export var vertical_lock_smooth_speed: float = 6.0
|
@export var vertical_lock_smooth_speed: float = 6.0
|
||||||
@ -29,6 +30,7 @@ var _head_base_rot: Vector3
|
|||||||
var _vertical_lock_factor: float = 1.0
|
var _vertical_lock_factor: float = 1.0
|
||||||
var _vertical_hold_timer: float = 0.0
|
var _vertical_hold_timer: float = 0.0
|
||||||
var _look_reference: Node3D
|
var _look_reference: Node3D
|
||||||
|
var _look_target: Node3D
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
@ -41,6 +43,7 @@ func _ready() -> void:
|
|||||||
_camera = _resolve_camera()
|
_camera = _resolve_camera()
|
||||||
_look_origin = get_node_or_null(look_origin_path) as Node3D
|
_look_origin = get_node_or_null(look_origin_path) as Node3D
|
||||||
_look_reference = get_node_or_null(look_reference_path) as Node3D
|
_look_reference = get_node_or_null(look_reference_path) as Node3D
|
||||||
|
_look_target = get_node_or_null(look_target_path) as Node3D
|
||||||
_head = get_node_or_null(head_path) as Node3D
|
_head = get_node_or_null(head_path) as Node3D
|
||||||
if _head:
|
if _head:
|
||||||
_head_base_rot = _head.rotation
|
_head_base_rot = _head.rotation
|
||||||
@ -55,14 +58,20 @@ func _process(_delta: float) -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _update_pupils() -> void:
|
func _update_pupils() -> void:
|
||||||
if _camera == null or not _camera.is_inside_tree():
|
if _look_target == null and look_target_path != NodePath(""):
|
||||||
|
_look_target = get_node_or_null(look_target_path) as Node3D
|
||||||
|
if _look_target == null:
|
||||||
|
var viewport_cam := get_viewport().get_camera_3d()
|
||||||
|
if viewport_cam != null and viewport_cam != _camera:
|
||||||
|
_camera = viewport_cam
|
||||||
|
elif _camera == null or not _camera.is_inside_tree():
|
||||||
_camera = _resolve_camera()
|
_camera = _resolve_camera()
|
||||||
if _camera == null:
|
if _look_target == null and _camera == null:
|
||||||
return
|
return
|
||||||
var origin := _look_origin
|
var origin := _look_origin
|
||||||
if origin == null:
|
if origin == null:
|
||||||
origin = self
|
origin = self
|
||||||
var target := _camera.global_position
|
var target := _look_target.global_position if _look_target != null else _camera.global_position
|
||||||
var dir_world := target - origin.global_position
|
var dir_world := target - origin.global_position
|
||||||
if dir_world.length_squared() <= 0.0001:
|
if dir_world.length_squared() <= 0.0001:
|
||||||
return
|
return
|
||||||
|
|||||||
@ -57,7 +57,12 @@ height = 1.1
|
|||||||
[node name="RepoBot" type="Node3D"]
|
[node name="RepoBot" type="Node3D"]
|
||||||
script = ExtResource("1_repo_bot")
|
script = ExtResource("1_repo_bot")
|
||||||
|
|
||||||
[node name="Body" type="StaticBody3D" parent="."]
|
[node name="Body" type="RigidBody3D" parent="."]
|
||||||
|
mass = 1.5
|
||||||
|
axis_lock_angular_x = true
|
||||||
|
axis_lock_angular_z = true
|
||||||
|
angular_damp = 8.0
|
||||||
|
linear_damp = 0.5
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Body"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Body"]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.55, 0)
|
||||||
|
|||||||
@ -43,6 +43,7 @@ script = ExtResource("1_a4mo8")
|
|||||||
|
|
||||||
[node name="RepoBot" parent="." instance=ExtResource("4_repo")]
|
[node name="RepoBot" parent="." instance=ExtResource("4_repo")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.9426608, 0, -4.4451966)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.9426608, 0, -4.4451966)
|
||||||
|
look_target_path = NodePath("../Player")
|
||||||
|
|
||||||
[node name="Thing" type="RigidBody3D" parent="."]
|
[node name="Thing" type="RigidBody3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -3.7986288)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -3.7986288)
|
||||||
@ -84,6 +85,7 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1, 0)
|
|||||||
shape = SubResource("BoxShape3D_2q6dc")
|
shape = SubResource("BoxShape3D_2q6dc")
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ground"]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="Ground"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.00053596497, 0.0075991154, -0.0019865036)
|
||||||
mesh = SubResource("BoxMesh_w7c3h")
|
mesh = SubResource("BoxMesh_w7c3h")
|
||||||
|
|
||||||
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="."]
|
||||||
@ -103,33 +105,6 @@ process_mode = 3
|
|||||||
visible = false
|
visible = false
|
||||||
script = ExtResource("3_tc7dm")
|
script = ExtResource("3_tc7dm")
|
||||||
|
|
||||||
[node name="PhoneUI" type="CanvasLayer" parent="."]
|
|
||||||
layer = 5
|
|
||||||
visible = false
|
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="PhoneUI"]
|
|
||||||
layout_mode = 3
|
|
||||||
anchors_preset = 15
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
|
|
||||||
[node name="PhoneFrame" type="ColorRect" parent="PhoneUI/Control"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 8
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_top = 0.5
|
|
||||||
anchor_right = 0.5
|
|
||||||
anchor_bottom = 0.5
|
|
||||||
offset_left = -180.0
|
|
||||||
offset_top = -320.0
|
|
||||||
offset_right = 180.0
|
|
||||||
offset_bottom = 320.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 2
|
|
||||||
color = Color(0.08, 0.08, 0.1, 1)
|
|
||||||
|
|
||||||
[node name="Control" type="Control" parent="Menu"]
|
[node name="Control" type="Control" parent="Menu"]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
@ -166,6 +141,33 @@ text = "Main Menu"
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Quit"
|
text = "Quit"
|
||||||
|
|
||||||
|
[node name="PhoneUI" type="CanvasLayer" parent="."]
|
||||||
|
layer = 5
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
[node name="Control" type="Control" parent="PhoneUI"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="PhoneFrame" type="ColorRect" parent="PhoneUI/Control"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -180.0
|
||||||
|
offset_top = -320.0
|
||||||
|
offset_right = 180.0
|
||||||
|
offset_bottom = 320.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
color = Color(0.08, 0.08, 0.1, 1)
|
||||||
|
|
||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
environment = SubResource("Environment_a4mo8")
|
environment = SubResource("Environment_a4mo8")
|
||||||
|
|
||||||
|
|||||||
@ -6,6 +6,8 @@ extends RigidBody3D
|
|||||||
@export var turn_speed := 2.0
|
@export var turn_speed := 2.0
|
||||||
@export var turn_accel := 8.0
|
@export var turn_accel := 8.0
|
||||||
@export var lateral_damp := 10.0
|
@export var lateral_damp := 10.0
|
||||||
|
@export var launch_impulse := 28.0
|
||||||
|
@export var launch_up_impulse := 6.0
|
||||||
@export var seat_path: NodePath
|
@export var seat_path: NodePath
|
||||||
@export var exit_path: NodePath
|
@export var exit_path: NodePath
|
||||||
@export var camera_path: NodePath
|
@export var camera_path: NodePath
|
||||||
@ -27,6 +29,8 @@ func _ready() -> void:
|
|||||||
interact_area.body_exited.connect(_on_interact_body_exited)
|
interact_area.body_exited.connect(_on_interact_body_exited)
|
||||||
if car_camera:
|
if car_camera:
|
||||||
car_camera.current = false
|
car_camera.current = false
|
||||||
|
contact_monitor = true
|
||||||
|
max_contacts_reported = 8
|
||||||
|
|
||||||
func _process(_delta: float) -> void:
|
func _process(_delta: float) -> void:
|
||||||
if _driver == null and _nearby_driver != null and Input.is_action_just_pressed("interact"):
|
if _driver == null and _nearby_driver != null and Input.is_action_just_pressed("interact"):
|
||||||
@ -56,6 +60,23 @@ func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
|||||||
var target_turn: float = -input2v.x * turn_speed * speed_factor
|
var target_turn: float = -input2v.x * turn_speed * speed_factor
|
||||||
angular_velocity.y = move_toward(angular_velocity.y, target_turn, turn_accel * state.step)
|
angular_velocity.y = move_toward(angular_velocity.y, target_turn, turn_accel * state.step)
|
||||||
|
|
||||||
|
if speed_factor > 0.2:
|
||||||
|
var hit_ids := {}
|
||||||
|
for i in state.get_contact_count():
|
||||||
|
var collider := state.get_contact_collider_object(i)
|
||||||
|
if collider is RigidBody3D and collider != self:
|
||||||
|
var collider_id := (collider as Node).get_instance_id()
|
||||||
|
if hit_ids.has(collider_id):
|
||||||
|
continue
|
||||||
|
hit_ids[collider_id] = true
|
||||||
|
var contact_pos := state.get_contact_collider_position(i)
|
||||||
|
var launch_dir := (contact_pos - global_position).normalized()
|
||||||
|
if launch_dir.length() <= 0.001:
|
||||||
|
var normal_world := (global_transform.basis * state.get_contact_local_normal(i)).normalized()
|
||||||
|
launch_dir = normal_world if normal_world.length() > 0.001 else forward.normalized()
|
||||||
|
var impulse := launch_dir * (launch_impulse * speed_factor) + Vector3.UP * launch_up_impulse
|
||||||
|
(collider as RigidBody3D).apply_central_impulse(impulse)
|
||||||
|
|
||||||
func _enter_vehicle(player: Node) -> void:
|
func _enter_vehicle(player: Node) -> void:
|
||||||
if seat == null:
|
if seat == null:
|
||||||
return
|
return
|
||||||
|
|||||||
@ -26,6 +26,9 @@ var _camera_pitch := 0.0
|
|||||||
var _in_vehicle := false
|
var _in_vehicle := false
|
||||||
var _vehicle_collision_layer := 0
|
var _vehicle_collision_layer := 0
|
||||||
var _vehicle_collision_mask := 0
|
var _vehicle_collision_mask := 0
|
||||||
|
var _vehicle_original_parent: Node = null
|
||||||
|
var _light_was_on := false
|
||||||
|
@onready var _flashlight: SpotLight3D = $SpotLight3D
|
||||||
|
|
||||||
@export var camera_follow_speed := 10.0
|
@export var camera_follow_speed := 10.0
|
||||||
|
|
||||||
@ -156,7 +159,7 @@ func _input(event):
|
|||||||
zoom_camera(ZOOM_FACTOR) # Zoom out
|
zoom_camera(ZOOM_FACTOR) # Zoom out
|
||||||
|
|
||||||
if event.is_action_pressed("player_light"):
|
if event.is_action_pressed("player_light"):
|
||||||
$SpotLight3D.visible = !$SpotLight3D.visible
|
_flashlight.visible = !_flashlight.visible
|
||||||
|
|
||||||
func zoom_camera(factor):
|
func zoom_camera(factor):
|
||||||
var new_fov = cam.fov * factor
|
var new_fov = cam.fov * factor
|
||||||
@ -168,7 +171,11 @@ func enter_vehicle(_vehicle: Node, seat: Node3D, vehicle_camera: Camera3D) -> vo
|
|||||||
sleeping = true
|
sleeping = true
|
||||||
collision_layer = 0
|
collision_layer = 0
|
||||||
collision_mask = 0
|
collision_mask = 0
|
||||||
|
_vehicle_original_parent = get_parent()
|
||||||
|
_light_was_on = _flashlight.visible
|
||||||
|
_flashlight.visible = false
|
||||||
if seat:
|
if seat:
|
||||||
|
reparent(seat, true)
|
||||||
global_transform = seat.global_transform
|
global_transform = seat.global_transform
|
||||||
if cam:
|
if cam:
|
||||||
cam.current = false
|
cam.current = false
|
||||||
@ -181,6 +188,10 @@ func exit_vehicle(exit_point: Node3D, vehicle_camera: Camera3D) -> void:
|
|||||||
sleeping = false
|
sleeping = false
|
||||||
collision_layer = _vehicle_collision_layer
|
collision_layer = _vehicle_collision_layer
|
||||||
collision_mask = _vehicle_collision_mask
|
collision_mask = _vehicle_collision_mask
|
||||||
|
if _vehicle_original_parent:
|
||||||
|
reparent(_vehicle_original_parent, true)
|
||||||
|
_vehicle_original_parent = null
|
||||||
|
_flashlight.visible = _light_was_on
|
||||||
if exit_point:
|
if exit_point:
|
||||||
global_transform = exit_point.global_transform
|
global_transform = exit_point.global_transform
|
||||||
if vehicle_camera:
|
if vehicle_camera:
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user