Improved camera
This commit is contained in:
parent
cceb6678f5
commit
6a6915ca08
@ -1,8 +1,6 @@
|
|||||||
class_name Camera
|
class_name Camera
|
||||||
extends Camera3D
|
extends Camera3D
|
||||||
|
|
||||||
@export_flags_3d_physics var collision_mask := 1
|
|
||||||
|
|
||||||
@export_group("Zoom")
|
@export_group("Zoom")
|
||||||
@export var zoom_speed := 0.5
|
@export var zoom_speed := 0.5
|
||||||
@export var zoom_interpolation := 10.0
|
@export var zoom_interpolation := 10.0
|
||||||
@ -10,12 +8,9 @@ extends Camera3D
|
|||||||
@export var zoom_max := 8.0
|
@export var zoom_max := 8.0
|
||||||
|
|
||||||
var target_distance: float
|
var target_distance: float
|
||||||
var occlusion_distance: float = far
|
|
||||||
var pivot: Node3D
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
target_distance = position.z
|
target_distance = position.z
|
||||||
pivot = get_parent()
|
|
||||||
Global.camera = self
|
Global.camera = self
|
||||||
|
|
||||||
func _input(event):
|
func _input(event):
|
||||||
@ -33,39 +28,20 @@ func on_distance_changed():
|
|||||||
target_distance = clampf(target_distance, zoom_min, zoom_max)
|
target_distance = clampf(target_distance, zoom_min, zoom_max)
|
||||||
Global.camera_attributes.dof_blur_far_distance = target_distance + 1.0
|
Global.camera_attributes.dof_blur_far_distance = target_distance + 1.0
|
||||||
|
|
||||||
|
func is_below_terrain():
|
||||||
|
return %CameraRays.occlusion_point.y > global_position.y
|
||||||
|
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
var distance := target_distance
|
var distance := target_distance
|
||||||
|
|
||||||
if occlusion_distance < target_distance:
|
if %CameraRays.occlusion_distance < target_distance:
|
||||||
distance = occlusion_distance
|
distance = %CameraRays.occlusion_distance - 0.5
|
||||||
|
|
||||||
|
if is_below_terrain():
|
||||||
|
position.z = distance
|
||||||
|
return
|
||||||
|
|
||||||
if abs(distance - position.z) < 0.01:
|
if abs(distance - position.z) < 0.01:
|
||||||
return
|
return
|
||||||
|
|
||||||
position.z = lerpf(position.z, distance, zoom_interpolation * delta)
|
position.z = lerpf(position.z, distance, zoom_interpolation * delta)
|
||||||
|
|
||||||
func _physics_process(_delta):
|
|
||||||
occlusion_distance = far
|
|
||||||
|
|
||||||
var corner: Vector2 = get_viewport().get_visible_rect().size
|
|
||||||
var space_state = get_world_3d().direct_space_state
|
|
||||||
|
|
||||||
send_ray(space_state, Vector2(0, 0))
|
|
||||||
send_ray(space_state, Vector2(corner.x, 0))
|
|
||||||
send_ray(space_state, Vector2(0, corner.y))
|
|
||||||
send_ray(space_state, Vector2(corner.x, corner.y))
|
|
||||||
send_ray(space_state, Vector2(corner.x / 2, corner.y / 2))
|
|
||||||
|
|
||||||
func send_ray(space_state: PhysicsDirectSpaceState3D, pos: Vector2):
|
|
||||||
var from := pivot.global_position
|
|
||||||
var to := project_position(pos, -1)
|
|
||||||
var query = PhysicsRayQueryParameters3D.create(from, to, collision_mask)
|
|
||||||
var result = space_state.intersect_ray(query)
|
|
||||||
|
|
||||||
if result:
|
|
||||||
var hit_point: Vector3 = result.position
|
|
||||||
var diff := hit_point - pivot.global_position
|
|
||||||
var distance := diff.length()
|
|
||||||
|
|
||||||
if distance < occlusion_distance:
|
|
||||||
occlusion_distance = distance
|
|
@ -1,9 +1,10 @@
|
|||||||
[gd_scene load_steps=5 format=3 uid="uid://cpdoq0oh84mfw"]
|
[gd_scene load_steps=6 format=3 uid="uid://cpdoq0oh84mfw"]
|
||||||
|
|
||||||
[ext_resource type="Script" path="res://camera/FollowPlayer.gd" id="1_48rtd"]
|
[ext_resource type="Script" path="res://camera/FollowPlayer.gd" id="1_48rtd"]
|
||||||
[ext_resource type="Script" path="res://camera/CameraPivot.gd" id="2_dylfm"]
|
[ext_resource type="Script" path="res://camera/CameraPivot.gd" id="2_dylfm"]
|
||||||
[ext_resource type="Script" path="res://camera/Camera.gd" id="2_pwdc2"]
|
[ext_resource type="Script" path="res://camera/Camera.gd" id="2_pwdc2"]
|
||||||
[ext_resource type="CameraAttributesPractical" uid="uid://b835orxyqq6w5" path="res://camera/CameraPractical.tres" id="3_olar0"]
|
[ext_resource type="CameraAttributesPractical" uid="uid://b835orxyqq6w5" path="res://camera/CameraPractical.tres" id="3_olar0"]
|
||||||
|
[ext_resource type="Script" path="res://camera/CameraRays.gd" id="5_5b07p"]
|
||||||
|
|
||||||
[node name="Follow" type="Marker3D"]
|
[node name="Follow" type="Marker3D"]
|
||||||
script = ExtResource("1_48rtd")
|
script = ExtResource("1_48rtd")
|
||||||
@ -23,3 +24,7 @@ fov = 45.0
|
|||||||
size = 10.0
|
size = 10.0
|
||||||
far = 1000.0
|
far = 1000.0
|
||||||
script = ExtResource("2_pwdc2")
|
script = ExtResource("2_pwdc2")
|
||||||
|
|
||||||
|
[node name="CameraRays" type="Node3D" parent="Pivot"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
script = ExtResource("5_5b07p")
|
||||||
|
@ -4,3 +4,4 @@
|
|||||||
exposure_multiplier = 0.5
|
exposure_multiplier = 0.5
|
||||||
dof_blur_far_transition = 50.0
|
dof_blur_far_transition = 50.0
|
||||||
dof_blur_near_enabled = true
|
dof_blur_near_enabled = true
|
||||||
|
dof_blur_near_distance = 1.8
|
||||||
|
38
client/camera/CameraRays.gd
Normal file
38
client/camera/CameraRays.gd
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
class_name CameraRays
|
||||||
|
extends Node3D
|
||||||
|
|
||||||
|
@export_flags_3d_physics var collision_mask := 1
|
||||||
|
|
||||||
|
var occlusion_distance: float = 1000
|
||||||
|
var occlusion_point: Vector3
|
||||||
|
var pivot: Node3D
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
pivot = get_parent()
|
||||||
|
|
||||||
|
func _physics_process(_delta):
|
||||||
|
occlusion_distance = Global.camera.far
|
||||||
|
|
||||||
|
var corner: Vector2 = get_viewport().get_visible_rect().size
|
||||||
|
var space_state = get_world_3d().direct_space_state
|
||||||
|
|
||||||
|
send_ray(space_state, Vector2(0, 0))
|
||||||
|
send_ray(space_state, Vector2(corner.x, 0))
|
||||||
|
send_ray(space_state, Vector2(0, corner.y))
|
||||||
|
send_ray(space_state, Vector2(corner.x, corner.y))
|
||||||
|
send_ray(space_state, Vector2(corner.x / 2, corner.y / 2))
|
||||||
|
|
||||||
|
func send_ray(space_state: PhysicsDirectSpaceState3D, pos: Vector2):
|
||||||
|
var from := pivot.global_position
|
||||||
|
var to := Global.camera.project_position(pos, -1)
|
||||||
|
var query = PhysicsRayQueryParameters3D.create(from, to, collision_mask)
|
||||||
|
var result = space_state.intersect_ray(query)
|
||||||
|
|
||||||
|
if result:
|
||||||
|
var hit_point: Vector3 = result.position
|
||||||
|
var diff := hit_point - pivot.global_position
|
||||||
|
var distance := diff.length()
|
||||||
|
|
||||||
|
if distance < occlusion_distance:
|
||||||
|
occlusion_distance = distance
|
||||||
|
occlusion_point = hit_point
|
Loading…
x
Reference in New Issue
Block a user