Posted: 2nd May 2023 0:01
Hello everyone, can anyone help me with an algorithm example to create a camera similar to some mmorpg?

like this video > https://youtu.be/0o8UD01QYjE?t=1375
Posted: 2nd May 2023 3:40
even better: courtesty of hendron (posted mere hours before your inquiry - does no one search anymore? )
Posted: 2nd May 2023 3:58
does no one search anymore?




I over search and read just about every little thing on my issues before asking.
Posted: 2nd May 2023 5:02
thank you for everyone's response!

I saw the post in question, but it didn't help me much... :c
even better: courtesty of hendron (posted mere hours before your inquiry - does no one search anymore? )


would you have any example of the camera rotating around the 3d model without doing some "Work around"?
Posted: 2nd May 2023 5:34
Hi, I just set this up and it is easy, the camera object is what follows the player, the camera is attached to the camera object and this is what pans and follows your player object.

I saw your video and it is the same.


But this is from the 3d physics example doing exactly what you want .Here

+ Code Snippet
global rawMouseX as float
global rawMouseY as float
global lockMouse as integer
global mouseSet as integer
global cameraAngleX as float
global cameraAngleY as float
global oldCamAngleX as float
global oldCamAngleY as float



function FreeFlightCameraUsingMouseAndArrowKeys(  cameraID as integer, speed as float)
	if GetMouseExists() and lockMouse = 0 
		rawMouseX = 0.0
		rawMouseY = 0.0
		if mouseSet = 1
			rawMouseX = ( GetDeviceWidth() / 2 ) -  GetRawMouseX() 
			rawMouseY = ( GetDeviceHeight() / 2 ) -  GetRawMouseY() 
			oldCamAngleX = cameraAngleX
			oldCamAngleY = cameraAngleY
			cameraAngleY = WrapAngle( cameraAngleY - rawMouseX * 0.2)
			cameraAngleX = WrapAngle( cameraAngleX - rawMouseY * 0.2)
			
			//came rotation limits..
			//Vertical
			if cameraAngleX <= 290.0 and cameraAngleX > 180.0  then cameraAngleX = 290.0
			if cameraAngleX >= 70.0 and cameraAngleX < 180.0 then cameraAngleX = 70.0

			cameraAngleX = CurveAngle( cameraAngleX, oldCamAngleX, speed  )
			cameraAngleY = CurveAngle( cameraAngleY, oldCamAngleY, speed  )

		endif
		SetRawMousePosition( GetDeviceWidth() / 2, GetDeviceHeight() / 2 )
		//SetRawMouseVisible does not work correctly bug in AGK
		//SetRawMouseVisible( 0 )
		mouseSet = 1
	endif
	SetCameraRotation( cameraID, cameraAngleX, cameraAngleY, 0.0 )
	if GetRawKeyReleased( 27 ) 
		lockMouse = lockMouse + 1
		if lockMouse = 2 then lockMouse = 0
		if GetMouseExists()  and lockMouse = 1 
			//SetRawMouseVisible does not work correctly bug in AGK
			//SetRawMouseVisible(1)
			mouseSet = 0
		endif
	endif
	if GetKeyboardExists()
		if GetRawKeyState( 37 )  then MoveCameraLocalX( cameraID, -1.0 * speed ) 
		if GetRawKeyState( 39 ) then MoveCameraLocalX( cameraID, 1.0 * speed ) 
		if GetRawKeyState( 38 ) then MoveCameraLocalZ( cameraID, 1.0 * speed ) 
		if GetRawKeyState( 40 ) then MoveCameraLocalZ( cameraID, -1.0 * speed ) 
	endif

// ################## Rick's additions (just a quick fix) :-)  ####################
// set camera on your character
    SetCameraPosition(1, GetObjectX(maskedSoldier),GetObjectY(maskedSoldier),GetObjectZ(maskedSoldier))
//align camera rotation with character POV
    SetCameraRotation( 1, 0,GetObjectAngleY(maskedSoldier)-180 , 0)
//move the camera behind you
    MoveCameraLocalZ(1, -44)
//move the camera up
    MoveCameraLocalY( 1, 75 )
// ################################################################ 

	
endfunction

function FreeFlightCameraUsingTouch( cameraID as integer, speed as float )
	if getmultitouchexists() = 1
		local touchX as float
		local touchY as float
		camMove = 0.0
		camStrafe = 0.0
		howmany = GetRawTouchCount( 0 ) 
		id = getrawfirsttouchevent( 0 )
		for t = 1 to howmany step 1
			touchX = ( getrawtouchcurrentx( id ) - getrawtouchstartx( id ) ) / 75
			touchY = ( getrawtouchcurrenty( id ) - getrawtouchstarty( id ) ) / 75
			movectrl = 0
			if getrawtouchstartx( id ) < 200 then movectrl = 1
			//If the start of touch y is greater then 450 then its a movement touch not rotation.
			if movectrl = 1
				camMove = -touchY * 1 * speed
				camStrafe = touchX * 1 * speed
			endif
			if movectrl = 0
				oldCamAngleX = cameraAngleX
				oldCamAngleY = cameraAngleY
				cameraAngleY = WrapAngle( cameraAngleY + touchX )
				cameraAngleX = WrapAngle( cameraAngleX + touchY )
				if cameraAngleX <= 290.0 and cameraAngleX > 180.0  then cameraAngleX = 290.0
				if cameraAngleX >= 70.0 and cameraAngleX < 180.0 then cameraAngleX = 70.0
				cameraAngleX = CurveAngle( cameraAngleX, oldCamAngleX, speed )
				cameraAngleY = CurveAngle( cameraAngleY, oldCamAngleY, speed )
			endif
			id = getrawnexttouchevent()
		next t
		MovecameraLocalZ( cameraID, camMove )
		MovecameraLocalX( cameraID, camStrafe )
		SetCameraRotation( cameraID, cameraAngleX, cameraAngleY, 0.0 )
	endif
endfunction

function FreeFlightCameraUsingVirtualJoysticks( cameraID as integer, speed as float )
	if GetVirtualJoystickExists( R_VirtualJoystick )
		oldCamAngleX = cameraAngleX
		oldCamAngleY = cameraAngleY
		cameraAngleY = WrapAngle( cameraAngleY + ( GetVirtualJoystickX( R_VirtualJoystick ) * 2.5 ) )
		cameraAngleX = WrapAngle( cameraAngleX + ( GetVirtualJoystickY( R_VirtualJoystick ) * 2.5 ) )
		if cameraAngleX <= 290.0 and cameraAngleX > 180.0  then cameraAngleX = 290.0
		if cameraAngleX >= 70.0 and cameraAngleX < 180.0 then cameraAngleX = 70.0
		cameraAngleX = CurveAngle( cameraAngleX, oldCamAngleX, speed )
		cameraAngleY = CurveAngle( cameraAngleY, oldCamAngleY, speed )
		SetCameraRotation( cameraID, cameraAngleX, cameraAngleY, 0.0 )
	endif
	if GetVirtualJoystickExists( L_VirtualJoystick )
		MovecameraLocalZ( cameraID, ( GetVirtualJoystickY( L_VirtualJoystick ) * -1.0 ) * speed )
		MovecameraLocalX( cameraID, GetVirtualJoystickX( L_VirtualJoystick ) * speed )
	endif
endfunction

//Returns a vector ID which has the forward direction of the camera.
function GetCameraForwardDirectionVector( cameraID as integer )
	x = sin( GetCameraAngleY( cameraID ) )
	z = cos( GetCameraAngleY( cameraID ) )
	y = -tan( GetCameraAngleX( cameraID ) )
	camVecID = CreateVector3( x, y, z )
endfunction camVecID
Posted: 2nd May 2023 15:21
would you have any example of the camera rotating around the 3d model without doing some "Work around"?


You're a game developer, embrace workarounds.

I can see why my example from the other thread doesn't fit your request, as it's a follow camera rather than an orbit camera. Here's a revised version. It even includes some (basic) camera collision. It won't get you 100% of the way there but it should get you started.

+ 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