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
|
## Scaling factor for additional force-based damage
|
||||||
@export var damage_force_scale := 0.01
|
@export var damage_force_scale := 0.01
|
||||||
|
|
||||||
|
var current_gravity: Vector3
|
||||||
|
|
||||||
var _last_contact_normal: Vector3 = Vector3.UP
|
var _last_contact_normal: Vector3 = Vector3.UP
|
||||||
var _position_on_last_wake: Vector3
|
var _position_on_last_wake: Vector3
|
||||||
var _awake := false
|
var _awake := false
|
||||||
|
@ -80,6 +82,7 @@ func _magnus_force() -> Vector3:
|
||||||
|
|
||||||
|
|
||||||
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
func _integrate_forces(state: PhysicsDirectBodyState3D) -> void:
|
||||||
|
current_gravity = state.total_gravity
|
||||||
if not _awake:
|
if not _awake:
|
||||||
# Triggered on first frame after waking
|
# Triggered on first frame after waking
|
||||||
_awake = true
|
_awake = true
|
||||||
|
|
|
@ -49,6 +49,7 @@ const WIDTH := 4
|
||||||
|
|
||||||
@export var draw_reoriented_basis := true
|
@export var draw_reoriented_basis := true
|
||||||
@export var draw_magnus_effect := true
|
@export var draw_magnus_effect := true
|
||||||
|
@export var draw_gravity_basis := true
|
||||||
|
|
||||||
@onready var physics_ball: GameBall = $\"..\"
|
@onready var physics_ball: GameBall = $\"..\"
|
||||||
|
|
||||||
|
@ -73,6 +74,19 @@ func _draw() -> void:
|
||||||
if draw_magnus_effect:
|
if draw_magnus_effect:
|
||||||
var end := camera.unproject_position(physics_ball.global_position + physics_ball._magnus_force() * MAGNUS_SCALE)
|
var end := camera.unproject_position(physics_ball.global_position + physics_ball._magnus_force() * MAGNUS_SCALE)
|
||||||
draw_line(start, end, COLOR_MAGNUS, WIDTH)
|
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"]
|
[sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_gc38m"]
|
||||||
|
@ -150,6 +164,7 @@ grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
script = SubResource("GDScript_p4v7o")
|
script = SubResource("GDScript_p4v7o")
|
||||||
draw_reoriented_basis = false
|
draw_reoriented_basis = false
|
||||||
|
draw_magnus_effect = false
|
||||||
|
|
||||||
[node name="SFX" type="Node3D" parent="."]
|
[node name="SFX" type="Node3D" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
|
@ -1,28 +1,49 @@
|
||||||
class_name OrbitalCamera extends Node3D
|
class_name OrbitalCamera extends Node3D
|
||||||
|
|
||||||
const POSITION_ACCELERATION := 4.0
|
const POSITION_ACCELERATION := 4.0
|
||||||
|
const BASIS_ACCELERATION := 4.0
|
||||||
|
const TARGETER_ACCELERATION := 7.0
|
||||||
|
|
||||||
@export var target: Node3D
|
@export var target: Node3D
|
||||||
@export var offset := Vector3(0, 1, 0)
|
@export var offset := Vector3(0, 1, 0)
|
||||||
|
|
||||||
@export var angular_speed := 0.007
|
@export var angular_speed := 0.007
|
||||||
|
|
||||||
|
var target_basis := Basis.IDENTITY
|
||||||
|
|
||||||
|
@onready var pivot: Node3D = %Pivot
|
||||||
@onready var camera: Camera3D = %Camera
|
@onready var camera: Camera3D = %Camera
|
||||||
|
@onready var targeter: Node3D = %Targeter
|
||||||
|
|
||||||
static var scene := preload("res://src/ui/camera/orbital_camera/orbital_camera.tscn")
|
static var scene := preload("res://src/ui/camera/orbital_camera/orbital_camera.tscn")
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
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
|
# Update position
|
||||||
global_position = global_position.lerp(
|
global_position = global_position.lerp(
|
||||||
target.global_position + offset, delta * POSITION_ACCELERATION
|
target.global_position + offset, delta * POSITION_ACCELERATION
|
||||||
)
|
)
|
||||||
|
|
||||||
# Update rotation
|
# 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
|
# Update phase angle
|
||||||
rotation.y += angular_speed
|
pivot.rotation.y += angular_speed
|
||||||
|
|
||||||
|
|
||||||
static func create(_target: Node3D) -> OrbitalCamera:
|
static func create(_target: Node3D) -> OrbitalCamera:
|
||||||
|
|
|
@ -5,12 +5,20 @@
|
||||||
[node name="OrbitalCamera" type="Node3D"]
|
[node name="OrbitalCamera" type="Node3D"]
|
||||||
script = ExtResource("1_nvlic")
|
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)
|
transform = Transform3D(1, 0, 0, 0, 0.913545, 0.406737, 0, -0.406737, 0.913545, 0, 0, 0)
|
||||||
spring_length = 3.2
|
spring_length = 3.2
|
||||||
|
|
||||||
[node name="Camera" type="Camera3D" parent="Pitch"]
|
[node name="CameraOffset" type="Node3D" parent="Pivot/Pitch"]
|
||||||
unique_name_in_owner = true
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 3)
|
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
|
current = true
|
||||||
far = 8192.0
|
far = 8192.0
|
||||||
|
|
Loading…
Reference in New Issue