Posted: 2nd May 2023 15:31
Originally posted as answers in two other threads.

Simple follow camera with smooth camera panning.

+ Code Snippet
type 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#


Simple orbit camera with basic camera collision

+ Code Snippet
type tPlayer
    objId
    moveSpeed as float
endtype

type tCamera
    distance as float
    currentPitch as float
    pitchRange as float
    targetHeightOffset as float
    collisionRadius as float
    mouseSensitivity as float
endtype

// mouse movement vars
global gMouseDeltaX as float
global gMouseDeltaY as float

// create player
Player as tPlayer
Player.objId = CreateObjectBox(0.5,2.0,0.4)
Player.moveSpeed = 4.0
SetObjectPosition(Player.objId, 0, 1.0, 0)
FixObjectPivot(Player.objId)
SetObjectCollisionMode(Player.objId, 0)

// create camera
Camera as tCamera
Camera.distance = 4.0
Camera.pitchRange = 80.0
Camera.targetHeightOffset = 1.8
Camera.collisionRadius = 0.25
Camera.mouseSensitivity = 0.2

// create ground
oGround = CreateObjectPlane(30, 30)
SetObjectColor(oGround, 64, 128, 64, 255)
RotateObjectGlobalX(oGround,90)
FixObjectPivot(oGround)

// create some random boxes to test camera collision
for i = 0 to 10
    height# = random(1,2)
    b = CreateObjectBox(1, height#, 1)
    SetObjectColor(b, 128, 64, 64, 255)
    SetObjectPosition(b, random(0,20) - 10, height# / 2, random(0, 20) - 10)
next i

// display
SetWindowSize(1280,720,0)
SetVirtualResolution(1280,720)
SetSyncRate(60,1)
UseNewDefaultFonts(1)

// other setup
SetRawMouseVisible(0)
SetCameraRange(1,0.01,1000)

// main loop
while not GetRawKeyState(27)
    delta# = GetFrameTime()

    // calculate mouse delta
    gMouseDeltaX = GetRawMouseX() - gMouseDeltaX
    gMouseDeltaY = GetRawMouseY() - gMouseDeltaY

    HandlePlayerMovement(Player, delta#)
    HandleCamera(Camera, Player.objId, delta#)
    HandlePlayerRotation(Player, delta#)

    // re-center the mouse
    SetRawMousePosition(GetVirtualWidth()/2, GetVirtualHeight()/2)

    gMouseDeltaX = GetRawMouseX()
    gMouseDeltaY = GetRawMouseY()

    print("Move with WASD")
    print("Mouse controls the camera")

    sync()
endwhile


function HandlePlayerMovement(player ref as tPlayer, delta as float)
    moveV# = GetRawKeyState(87) - GetRawKeyState(83)
    moveH# = GetRawKeyState(68) - GetRawKeyState(65)

    // normalize the movement vector if needed,
    // so that speed is consistent in all directions
    mag# = sqrt(moveV# * moveV# + moveH# * moveH#)
    if mag# > 1.0
        moveV# = moveV# / mag#
        moveH# = moveH# / mag#
    endif

    MoveObjectLocalZ(player.objId, moveV# * player.moveSpeed * delta)
    MoveObjectLocalX(player.objId, moveH# * player.moveSpeed * delta)
endfunction


function HandlePlayerRotation(player ref as tPlayer, delta as float)

    // get camera forward vector on XZ plane
    cOldX# = GetCameraX(1)
    cOldY# = GetCameraY(1)
    cOldZ# = GetCameraZ(1)
    MoveCameraLocalZ(1,1)
    cForwardX# = GetCameraX(1) - cOldX#
    cForwardZ# = GetCameraZ(1) - cOldZ#
    SetCameraPosition(1, cOldX#, cOldY#, cOldZ#)

    // rotate player to camera orientation
    SetObjectLookAt(player.objId, GetObjectX(player.objId) + cForwardX#, GetObjectY(player.objId), GetObjectZ(player.objId) + cForwardZ#, 0)

endfunction


function HandleCamera(camera ref as tCamera, targetObject, delta as float)

    // store the target position
    tx# = GetObjectX(targetObject)
    ty# = GetObjectY(targetObject) + camera.targetHeightOffset
    tz# = GetObjectZ(targetObject)

    // position camera at target
    SetCameraPosition(1, tx#, ty#, tz#)

    // rotate camera on Y axis with mouse X
    SetCameraRotation(1, 0, GetCameraAngleY(1) + gMouseDeltaX * camera.mouseSensitivity, 0)

    // rotate camera on X axis with mouse Y
    camera.currentPitch = camera.currentPitch + gMouseDeltaY * camera.mouseSensitivity
    camera.currentPitch = ClampFloat(camera.currentPitch, -camera.pitchRange, camera.pitchRange)
    RotateCameraLocalX(1, camera.currentPitch)

    // move camera back by distance
    MoveCameraLocalZ(1, -camera.distance)

    // detect camera collision and move camera forward if needed
    hit = ObjectSphereCast(0, tx#, ty#, tz#, GetCameraX(1), GetCameraY(1), GetCameraZ(1), camera.collisionRadius)
    if hit
        SetCameraPosition(1, GetObjectRayCastX(0), GetObjectRayCastY(0), GetObjectRayCastZ(0))
    endif
endfunction


function ClampFloat(in as float, min as float, max as float)
    if in < min then exitfunction min
    if in > max then exitfunction max
endfunction in