kuligs2 Basically add the to any character the Camroot/ and its child nodes as per picture above. Put the camera in 3D local space at the end of the spring arm. in my case spring arm is 5m long so its at x=5m in local units. THen add script to camroot/ node:
extends Node3D
@export_category("Camera target")
@export var camera_target : Node3D #THE CAMERA WILL FOLLOW THIS NODE
@export_category("Exclude Collision")
@export var exclude_node : Node3D # Usually the same node that camera follows
#@export_category("Wait Time")
#@export var wait_time : float #How long for the camera to start following the node, can leave it at 0 too
var point_position : Vector3 #The global position of the node we want the camera to follow
var speed := 7.0 #How fast the camera will reach its destination
var offset_x = -1.24
var offset_y = 1.24
var offset_z = 1.24
var h_sensitivity = 0.20
var v_sensitivity = 0.20
var h_acceleration = 10.0
var v_acceleration = 10.0
var camrot_h = 0.0
var camrot_v = 0.0
var cam_v_min = -75.0 # degrees
var cam_v_max = 55.0 # degrees
var zoom_min = 1
var zoom_max = 7
var zoom_step = 1
# Called when the node enters the scene tree for the first time.
func _ready():
$h/v.position.x = offset_x
$h/v.position.z = offset_z
$h/v.position.y = offset_y
$h/v/SpringArm3D.add_excluded_object(exclude_node) # removes collision with player
$h/v/SpringArm3D.add_excluded_object($h/v/SpringArm3D)
func _input(event):
if event is InputEventMouseMotion:
camrot_h -= event.relative.x * h_sensitivity
camrot_v -= event.relative.y * v_sensitivity
func _process(delta):
follow_player_new(delta)
camrot_v = clamp(camrot_v,cam_v_min, cam_v_max)
delta*auto_rotate_speed)
$h.rotation_degrees.y=lerp($h.rotation_degrees.y,camrot_h, delta*h_acceleration)
$h/v.rotation_degrees.x=lerp($h/v.rotation_degrees.x,camrot_v, delta*v_acceleration)
if Input.is_action_pressed("zoom_in"):
zoom_camera_in(delta)
if Input.is_action_pressed("zoom_out"):
zoom_camera_out(delta)
# delayed camera folow
func follow_player_new(delta):
var direction = self.global_position - camera_target.global_position #Where we want to move
var point_current_position = point_position
var point_last_position = camera_target.global_position
if point_last_position != point_current_position:
self.transform.origin -= direction * speed * delta
func zoom_camera_in(delta):
var current_length = $h/v/SpringArm3D.spring_length
$h/v/SpringArm3D.spring_length = clamp(current_length - (zoom_step*delta*h_acceleration),zoom_min,zoom_max)
pass
func zoom_camera_out(delta):
var current_length = $h/v/SpringArm3D.spring_length
$h/v/SpringArm3D.spring_length = clamp(current_length + (zoom_step*delta*h_acceleration),zoom_min,zoom_max)
pass