How do I program camera to follow 3D player but not rotate?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By winniethewind

Im currently working on a prototype utilizing a third person camera without rotation, meaning the player can rotate in all directions but the camera cannot. The camera and kinematicbody nodes are seperate, and while using a direction vector to move the player, I’m calling the camera to translate or move with the player each time I press up.

Example:

var cameraspatial = get_node("CameraSpatial")

if Input.is_action_pressed("ui_up"):
	#player movement
	dir += Vector3(0,0,1)
	#camera movement
	cameraspatial.translate(Vector3(0,0,1))

How could I stop the camera from moving as the player stops or hits a wall?

Also if I rapidly press the up arrow the player seems to move forward ever so slightly, moving away further from the camera, which is not a desired effect. Which leaves me to assume that the camera is not tied exactly to the camera. Any suggestions or help would be much appreciated.

UPDATE: so I did this:

if velocity.z == 0:
	gimbal.translate(Vector3(0,0,0))
if velocity.x == 0:
	gimbal.translate(Vector3(0,0,0))		

This stops the camera from moving, and it works fine. But if I press the up key rapidly as I said before, I can move the player out of sync with the camera, and I don’t know exactly why its doing that. I’m unsure if its the player acceleration, I’m thinking of making a gif of exactly what the problem is.

Heres my kinematicBody code:

extends KinematicBody

var gravity = -9.8
var velocity = Vector3()
var animplayer
var character
var gimbal

const MAX_SPEED = 25
const ACCELERATION = 3
const DE_ACCELERATION = 15
const DEADZONE = 0.2

const JUMP_SPEED = 7
	
func _ready():
	
	animplayer = get_node("AnimationPlayer")
	character = get_node(".")
	gimbal = get_parent().get_node("gimbal")
		
func _physics_process(delta):
	
	var dir = Vector3(0,0,0)
	var ismoving = false

	if Input.is_action_pressed("ui_up"):
		dir +=	Vector3(0,0,1)
		gimbal.translate(Vector3(0,0,velocity.z * delta))
		ismoving = true

	dir.y = 0
	dir = dir.normalized()
	
	velocity.y += delta * gravity
	
	var hv = velocity
	hv.y = 0
	
	if velocity.y > 0:
		gravity = -20
	else:
		gravity = -30 
	
	var new_pos = dir * MAX_SPEED
	var accel = DE_ACCELERATION
	
	if dir.dot(hv) > 0:
		accel = ACCELERATION
	
	hv = hv.linear_interpolate(new_pos, accel * delta)
	
	velocity.x = hv.x
	velocity.z = hv.z
	
	velocity = move_and_slide(velocity, Vector3(0,1,0))
	
	#set rotation
	if ismoving == true:

		var angle = atan2(hv.x, hv.z)
		var char_rot = character.get_rotation()
		
		char_rot.y = angle
		character.set_rotation(char_rot)
		
	if (is_on_floor() and Input.is_action_pressed("ui_accept")):
		velocity.y = JUMP_SPEED
		
	#Set animation
		
	var speed = hv.length() / MAX_SPEED
	get_node("AnimationTreePlayer").blend2_node_set_amount("BlendRun", speed)
	

Also, the gimbal has a camera attached.

:bust_in_silhouette: Reply From: dodgyville

I wonder if you’d have better result if you calculated the camera on the position of the character instead of moving them both separately

Thanks for your comment. Yes this does work better but the camera doesnt take the acceleration and deacceleration into consideration.

	if Input.is_action_pressed("ui_up"):
	dir +=	Vector3(0,0,1)
	gimbal.translation.z = character.translation.z
	ismoving = true

So everytime you let go of the up arrow, the camera will stop immediately while the character slows down but still steps too far in front of the camera, meaning the camera doesn’t follow the deacceleration. Once I press the up arrow again, the camera catches up to the player by abruptly shifting to its translation.

UPDATE:

Once again thanks. I decided to take the translation code outside the Input function so the camera is calculating the player position constantly. It worked! Follows the acceleration exactly! Much appreciated! :slight_smile:

winniethewind | 2018-02-27 13:47