generated from krampus/template-godot4
Camera adjusts to gravity normal
This commit is contained in:
parent
317f77c358
commit
bfe2ca46d4
|
@ -38,6 +38,8 @@ const MAGNUS_EPSILON := 1e-3
|
|||
## Scaling factor for additional force-based damage
|
||||
@export var damage_force_scale := 0.01
|
||||
|
||||
var current_gravity: Vector3
|
||||
|
||||
var _last_contact_normal: Vector3 = Vector3.UP
|
||||
var _position_on_last_wake: Vector3
|
||||
var _awake := false
|
||||
|
@ -80,6 +82,7 @@ func _magnus_force() -> Vector3:
|
|||
|
||||
|
||||
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
||||
current_gravity = state.total_gravity
|
||||
if not _awake:
|
||||
# Triggered on first frame after waking
|
||||
_awake = true
|
||||
|
|
|
@ -49,6 +49,7 @@ const WIDTH := 4
|
|||
|
||||
@export var draw_reoriented_basis := true
|
||||
@export var draw_magnus_effect := true
|
||||
@export var draw_gravity_basis := true
|
||||
|
||||
@onready var physics_ball: GameBall = $\"..\"
|
||||
|
||||
|
@ -73,6 +74,19 @@ func _draw() -> void:
|
|||
if draw_magnus_effect:
|
||||
var end := camera.unproject_position(physics_ball.global_position + physics_ball._magnus_force() * MAGNUS_SCALE)
|
||||
draw_line(start, end, COLOR_MAGNUS, WIDTH)
|
||||
|
||||
if draw_gravity_basis:
|
||||
var orbital: Node3D = camera.get_parent_node_3d().get_parent_node_3d().get_parent_node_3d()
|
||||
var up := -physics_ball.current_gravity.normalized()
|
||||
var right := up.cross(orbital.global_basis.z).normalized()
|
||||
var forward := right.cross(up).normalized()
|
||||
|
||||
var end_x := camera.unproject_position(physics_ball.global_position + right)
|
||||
var end_y := camera.unproject_position(physics_ball.global_position + up)
|
||||
var end_z := camera.unproject_position(physics_ball.global_position + forward)
|
||||
draw_line(start, end_x, COLOR_X, WIDTH)
|
||||
draw_line(start, end_y, COLOR_Y, WIDTH)
|
||||
draw_line(start, end_z, COLOR_Z, WIDTH)
|
||||
"
|
||||
|
||||
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_gc38m"]
|
||||
|
@ -150,6 +164,7 @@ grow_horizontal = 2
|
|||
grow_vertical = 2
|
||||
script = SubResource("GDScript_p4v7o")
|
||||
draw_reoriented_basis = false
|
||||
draw_magnus_effect = false
|
||||
|
||||
[node name="SFX" type="Node3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
|
|
@ -1,28 +1,49 @@
|
|||
class_name OrbitalCamera extends Node3D
|
||||
|
||||
const POSITION_ACCELERATION := 4.0
|
||||
const BASIS_ACCELERATION := 4.0
|
||||
const TARGETER_ACCELERATION := 7.0
|
||||
|
||||
@export var target: Node3D
|
||||
@export var offset := Vector3(0, 1, 0)
|
||||
|
||||
@export var angular_speed := 0.007
|
||||
|
||||
var target_basis := Basis.IDENTITY
|
||||
|
||||
@onready var pivot: Node3D = %Pivot
|
||||
@onready var camera: Camera3D = %Camera
|
||||
@onready var targeter: Node3D = %Targeter
|
||||
|
||||
static var scene := preload("res://src/ui/camera/orbital_camera/orbital_camera.tscn")
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var up := Vector3.UP
|
||||
# If target is a game ball, realign to gravity
|
||||
if target is GameBall:
|
||||
up = -(target as GameBall).current_gravity.normalized()
|
||||
var right := up.cross(global_basis.z).normalized()
|
||||
var forward := right.cross(up).normalized()
|
||||
target_basis = Basis(right, up, forward)
|
||||
|
||||
# Slerp to basis
|
||||
global_basis = global_basis.slerp(target_basis, delta * BASIS_ACCELERATION)
|
||||
|
||||
# Update position
|
||||
global_position = global_position.lerp(
|
||||
target.global_position + offset, delta * POSITION_ACCELERATION
|
||||
)
|
||||
|
||||
# Update rotation
|
||||
camera.look_at(target.global_position)
|
||||
#camera.look_at(target.global_position, up)
|
||||
targeter.look_at(target.global_position, up)
|
||||
camera.global_basis = camera.global_basis.slerp(
|
||||
targeter.global_basis.orthonormalized(), delta * TARGETER_ACCELERATION
|
||||
)
|
||||
|
||||
# Update phase angle
|
||||
rotation.y += angular_speed
|
||||
pivot.rotation.y += angular_speed
|
||||
|
||||
|
||||
static func create(_target: Node3D) -> OrbitalCamera:
|
||||
|
|
|
@ -5,12 +5,20 @@
|
|||
[node name="OrbitalCamera" type="Node3D"]
|
||||
script = ExtResource("1_nvlic")
|
||||
|
||||
[node name="Pitch" type="SpringArm3D" parent="."]
|
||||
[node name="Pivot" type="Node3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="Pitch" type="SpringArm3D" parent="Pivot"]
|
||||
transform = Transform3D(1, 0, 0, 0, 0.913545, 0.406737, 0, -0.406737, 0.913545, 0, 0, 0)
|
||||
spring_length = 3.2
|
||||
|
||||
[node name="Camera" type="Camera3D" parent="Pitch"]
|
||||
unique_name_in_owner = true
|
||||
[node name="CameraOffset" type="Node3D" parent="Pivot/Pitch"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3)
|
||||
|
||||
[node name="Targeter" type="Node3D" parent="Pivot/Pitch/CameraOffset"]
|
||||
unique_name_in_owner = true
|
||||
|
||||
[node name="Camera" type="Camera3D" parent="Pivot/Pitch/CameraOffset"]
|
||||
unique_name_in_owner = true
|
||||
current = true
|
||||
far = 8192.0
|
||||
|
|
Loading…
Reference in New Issue