The smoothing can be done by interpolating between the player y angle and the camera's current y angle each frame before moving the camera back on it's z axis. Here's an example that uses a dummy object as the camera's "parent" (the interpolation is done on this object instead of the camera) and SetCameraLookAt() to point at the player.
+ Code Snippettype tPlayer
objId
moveSpeed as float
turnSpeed as float
endtype
type tCamera
dummyId
distance as float
height as float
lookHeight as float
smoothing as float
endtype
// display
SetWindowSize(1280, 720, 0)
SetVirtualResolution(1280, 720)
SetSyncRate(0, 1)
UseNewDefaultFonts(1)
// make player
Player as tPlayer
Player.objId = CreateObjectBox(0.5, 2.0, 0.4)
Player.moveSpeed = 2.0
Player.turnSpeed = 90.0
MoveObjectLocalY(Player.objId, 1.0)
FixObjectPivot(Player.objId)
// make camera
Camera as tCamera
Camera.dummyId = CreateObjectBox(1,1,1)
Camera.distance = 5.0
Camera.height = 2.0
Camera.lookHeight = 1.8
Camera.smoothing = 0.1 // this should be set between 0 and 1
SetObjectVisible(Camera.dummyId, 0)
// make ground
oGround = CreateObjectPlane(20, 20)
SetObjectColor(oGround, 64, 128, 64, 255)
RotateObjectGlobalX(oGround, 90)
FixObjectPivot(oGround)
do
delta# = GetFrameTime()
HandlePlayer(Player, delta#)
HandleCamera(Camera, Player.objId, delta#)
print("Move with WASD")
sync()
loop
function HandlePlayer(player ref as tPlayer, delta as float)
// handle rotation
turn# = (GetRawKeyState(68) - GetRawKeyState(65)) * player.turnSpeed * delta
RotateObjectGlobalY(player.objId, turn#)
// handle movement
move# = (GetRawKeyState(87) - GetRawKeyState(83)) * player.moveSpeed * delta
MoveObjectLocalZ(player.objId, move#)
endfunction
function HandleCamera(camera ref as tCamera, targetObject, delta as float)
// set camera dummy to target position
SetObjectPosition(camera.dummyId, GetObjectX(targetObject), GetObjectY(targetObject), GetObjectZ(targetObject))
// lerp the camera dummy y rotation smoothly to target y rotation.
// the 1.0 - pow(smoothing, delta) formula creates framerate indepenence
ylerp# = LerpAngle(GetObjectAngleY(camera.dummyId), GetObjectAngleY(targetObject), 1.0 - pow(camera.smoothing, delta))
SetObjectRotation(camera.dummyId, 0, ylerp#, 0)
// move camera dummy back by distance and up by height
MoveObjectLocalZ(camera.dummyId, -camera.distance)
MoveObjectLocalY(camera.dummyId, camera.height)
// position camera at dummy
SetCameraPosition(1, GetObjectX(camera.dummyId), GetObjectY(camera.dummyId), GetObjectZ(camera.dummyId))
// point camera at target + lookHeight
SetCameraLookAt(1, GetObjectX(targetObject), GetObjectY(targetObject) + camera.lookHeight, GetObjectZ(targetObject), 0)
endfunction
// Lerp between two angles, taking shortest path
function LerpAngle(a as float, b as float, t as float)
if abs(b-a) > 180
if b > a
a = a + 360
else
b = b + 360
endif
endif
l# = a + (b-a) * t
endfunction l#