Can someone walk me through creating third person camera movement with mouse?

Started by William, May 07, 2023, 17:24:37

Previous topic - Next topic

William

im still interested in oldschool app/gamedev

Midimaster

william, you really should communicate a little bit more...

what is your plan? A third person? Like a drone? attached to the first person?. free movement of the camera or pointed always to the first person? Third person walks on terrain? Descripe what features this camera should have.

What  is your current code related to this feature?

 etc...

 
...back from Egypt

William

Quote from: Midimaster on May 08, 2023, 06:05:15william, you really should communicate a little bit more...

what is your plan? A third person? Like a drone? attached to the first person?. free movement of the camera or pointed always to the first person? Third person walks on terrain? Descripe what features this camera should have.

What  is your current code related to this feature?

 etc...

 
well im trying to code third person cam but im having trouble wrapping my head around it. its an open source project.

third person cam around the player entity. this is my project here https://github.com/zarosath/blitzmax-blitzKingdoms

not quite third person control yet also when i try to move the player entity it moves the cam instead
im still interested in oldschool app/gamedev

Midimaster

This is what we need to know:

What should happen (with the camera) if the players moves?
What should happen... if the player turns around?
Should both have a fixed distance?

And the altitude? Is your wish camera like a drone? Or is it walking behind the player?

A where is the camera looking? Always points to the player's body?
Or in the direction ahead?
Or in the direction, where the player looks?

A view onto your "non working" camera code is not helpful to us. But we need to know your description (in words!) how you wish the camera...


...back from Egypt

William

okay when the player moves the camera follows. third person or over the shoulder camera some distance behind the player entity. though when the mouse moves i would like it to turn the player entity left or right. i am not sure how to describe third person camera movement except its common mmorpg style such as WoW.

Thanks for responding btw
im still interested in oldschool app/gamedev

Midimaster

When you are not able to transform your observations (WoW) into clear (english language) movement/turn-rules, you will not be able to transform this into code! 

are you in discord?

it all start with....

"when the player.... then the camera...."

f.e.

when the player move ahead, the camera follows behind him

when the player turn to the left, the camera orbits him to the right to be again be3hind him

and so on...
...back from Egypt

Midimaster

you have to bring all three together: pivot, player and camera.

Pivot ist the master, it contains the player and the camera. Player stays always at 0/0/0 and camera always at 0/0/-dist

Pivot is the actor that you need to move/turn with the KEYs to walk around

In this constellation the camera stays behind the player when he moves or changes direction.

CameraFollow.gif


what would you like to achieve with this:

    TurnEntity pivot,0,(-x_speed),0    'turn player Left/Right   ???
    TurnEntity camera,y_speed,0,0    'tilt camera     ???

this would look like the player is looking around only

and the camera would also look left and right and does not longer focus on the player.

Is this what you want?
...back from Egypt

Naughty Alien

..this is 3rd person camera for B3D, which is good start to see how things work, so porting to openB3D/BMX should be very straightforward and good practice at same time..

; SuperCam!
;
; by PsychicParrot 2003
;
;
; Usage : SuperCam(cam,ent,cspeed#,dist#,hite#,xrot#,tilt#)
;
;

Graphics3D 1280,1024,32,2
SetBuffer=BackBuffer()
Global FreeLookXS#, FreeLookZS#, FreeLookRotXS#, FreeLookRotYS#

Global campivot=CreateCube() ; create pivot for camera
Global camera=CreateCamera()  ; create camera (!!!)

; ---------------------- THIS IS ALL JUST TO POPULATE THE WORLD WITH SOME RUBBISH ---------------

Global light=CreateLight()
Global player=CreateCube()    ; create simple player
Global Player_Free_Look=CreatePivot(player)
Global plane=CreatePlane()   ; create simple floor
MoveEntity player,0,1,0
; Create texture of size 256x256
tex=CreateTexture(256,256)

; Set buffer - texture buffer
SetBuffer TextureBuffer(tex)

; Clear texture buffer with background white color
For i=1 To 10
Color Rnd(0,255),Rnd(0,255),Rnd(0,255)
Rect Rnd(0,256),Rnd(0,256),Rnd(0,256),Rnd(0,256)
Next

; Texture cube with texture
EntityTexture plane,tex
EntityTexture player,tex

; Set buffer - backbuffer
SetBuffer BackBuffer()

;camera look variables
; ------------------------------------------------------------------------------------------------

While Not KeyHit(1)
;object movement according to mouse pointer position

FreeLook(Player,Player_Free_Look, .1)

SuperCam(camera,player,.08,8,4,0,0)

RenderWorld
VWait:Flip False

Wend

End



Function SuperCam(cam,ent,cspeed#,dist#,hite#,xrot#,tilt#)

TFormPoint 0,hite#,-dist#,ent,0

cx#=(TFormedX()-EntityX(cam))*cspeed#
cy#=(TFormedY()-EntityY(cam))*cspeed#
cz#=(TFormedZ()-EntityZ(cam))*cspeed#

TranslateEntity cam,cx,cy,cz
PointEntity cam,ent
RotateEntity cam,xrot#,EntityYaw(cam),tilt#

End Function

Function FreeLook(Object_Horizontal,Object_Vertical, sp# = .1)
If sp# > 0 Then
    FreeLookXS# = (FreeLookXS# + ((KeyDown(32) Or KeyDown(205)) - (KeyDown(30) Or KeyDown(203))) * sp#) * .75
    FreeLookZS# = (FreeLookZS# + ((KeyDown(17) Or KeyDown(200)) - (KeyDown(31) Or KeyDown(208))) * sp#) * .75
    MoveEntity Object_Horizontal, FreeLookXS#, 0, FreeLookZS#
EndIf
FreeLookRotXS# = ((MouseXSpeed() - FreeLookRotXS#) * .2 + FreeLookRotXS#) * .45
FreeLookRotYS# = ((MouseYSpeed() - FreeLookRotYS#) * .2 + FreeLookRotYS#) * .45
If EntityPitch(Object_Vertical) + FreeLookRotYS# < -89 pitch# = -89 ElseIf EntityPitch(Object_Vertical) + FreeLookRotYS# > 89 pitch# = 89 Else pitch# = EntityPitch(Object_Vertical) + FreeLookRotYS#
yaw# = -FreeLookRotXS# + EntityYaw(Object_Horizontal)
RotateEntity Object_Horizontal, 0, yaw#, 0
RotateEntity Object_Vertical, pitch#, 0, 0
MoveMouse GraphicsWidth() / 2, GraphicsHeight() / 2
End Function

angros47

You can also use an action, for example with ActTrackByDistance or ActTrackByPoint

William

Quote from: Midimaster on May 09, 2023, 00:08:50you have to bring all three together: pivot, player and camera.

Pivot ist the master, it contains the player and the camera. Player stays always at 0/0/0 and camera always at 0/0/-dist

Pivot is the actor that you need to move/turn with the KEYs to walk around

In this constellation the camera stays behind the player when he moves or changes direction.

CameraFollow.gif


what would you like to achieve with this:

    TurnEntity pivot,0,(-x_speed),0    'turn player Left/Right   ???
    TurnEntity camera,y_speed,0,0    'tilt camera     ???

this would look like the player is looking around only

and the camera would also look left and right and does not longer focus on the player.

Is this what you want?
perhaps, it may be best to keep it simple.
why turn a pivot instead of the player entity? so doing parent/child entity?

i have been afk real life but i am back on today
im still interested in oldschool app/gamedev

Dabz

Don't forget, in the Blitz3D samples there was a sorta Mario3D example...

$BLITZ3D_ROOT$/samples/mak/castle.bb

Might be worth a look as well.

Dabz
Intel Core i5 6400 2.7GHz, NVIDIA GeForce GTX 1070 (8GB), 16Gig DDR4 RAM, 256GB SSD, 1TB HDD, Windows 10 64bit

William

sweet. Thanks. I assume the entity pivot is for collisions midi master?
im still interested in oldschool app/gamedev

William

Been up during the night working on this porting code from b3d/RemiD third person cam code sample, well it compiles but it doesnt work right but i do have several sample code i can reference for this. like i am learning the more i test code what each portion does.
it would be cool if we could get this working together. https://github.com/zarosath/blitzmax-blitzKingdoms/tree/master

@Midimaster its a Work in progress, CameraFunctions works the camera how i want it.


Thank you for the help ya'all, i want to play this game i am coding :P its a long term project that i may or may not finish
im still interested in oldschool app/gamedev

Midimaster

Quote from: William on May 14, 2023, 07:32:16... I assume the entity pivot is for collisions midi master?

No it is important for the movement.A pivot is a master body, that you always use if you want to move 2 things in the same direction. A following camera is a perfect example for this. Look at the pivot as it is the player. The 3D-model of your player is a child at 0/0/0. If you now turn the pivot the 3D-model turn, too. But the advantage is that you now can add a second object as a child, that turns synchron too. And if you position it behind (0/0/-1)the 3D model, it keeps behind when turning and so it looks like it would rotate around the 3D actor.

CameraPivot.png

 
...back from Egypt

William

alright been trying to get something working right but so far its been failed attempts.


alright so this is the code, converted RemiD's code

check this out why is this not working right in openb3d/bmx?

'main program
Strict

Framework openb3d.b3dglgraphics
Import brl.randomdefault
Graphics3D 800,600, 0, 3

HideMouse()

SeedRnd(MilliSecs()) 

Const CFirstPerson% = 1
Const CThirdPerson% = 2
Global ViewMode% = CFirstPerson

Const GroupEnvironment% = 1
Const GroupCharacters% = 2

Global Camera:TCamera = CreateCamera() 
CameraRange(Camera,0.1,1000)
CameraClsColor(Camera,000,000,000)   

Local Origine:TMesh = CreateCube() 
ScaleMesh(Origine,0.1/2,1000.0,0.1/2)
EntityColor(Origine,255,000,000)
EntityFX(Origine,1)

Local GroundMesh:TMesh  = CreateCube()
ScaleMesh(GroundMesh,100.0/2,0.1/2,100.0/2)
PositionMesh(GroundMesh,100.0/2,-0.1/2,100.0/2)
EntityColor(GroundMesh,000,125,000)
EntityType(GroundMesh,GroupEnvironment)

Local PlayerCollider:TPivot = CreatePivot() 
PositionEntity(PlayerCollider,0,0,0) 
EntityRadius(PlayerCollider,0.25)
EntityType(PlayerCollider,GroupCharacters)

Local PlayerEyes:TPivot = CreatePivot()
PositionEntity(PlayerEyes,EntityX(PlayerCollider,True),EntityY(PlayerCollider,True)+1.6-0.25,EntityZ(PlayerCollider,True)+0.25)
EntityParent(PlayerEyes,PlayerCollider,True)

Local PlayerMesh:TMesh = CreateCube() 
ScaleMesh(PlayerMesh,0.5/2,1.7/2,0.25/2) 
PositionMesh(PlayerMesh,0,1.7/2,0) 
EntityColor(PlayerMesh,000,000,125) 
PositionEntity(PlayerMesh,EntityX(PlayerCollider,True),EntityY(PlayerCollider,True)-0.25,EntityZ(PlayerCollider,True)) 
EntityParent(PlayerMesh,PlayerCollider,True) 

ViewMode = CFirstPerson

PositionEntity(PlayerCollider,5,0.25+0.01,5)

Local PlayerColliderYaw:Float = 0
Local PlayerEyesPitch:Float = 0
Local PlayerIsOnGround:Int = 0

Local PlayerVX:Float = 0
Local PlayerVZ:Float = 0
Local PlayerVY:Float = 0
Local PlayerOldX:Float = 0
Local PlayerOldZ:Float = 0
Local PlayerNewX:Float = 0
Local PlayerNewZ:Float = 0

Local DirectLight:TLight = CreateLight(1) 
LightColor(DirectLight,125,125,125) 
PositionEntity(DirectLight,0,128.0,-128.0) 
RotateEntity(DirectLight,45,0,0) 
AmbientLight(063,063,063)

Collisions(GroupCharacters,GroupEnvironment,2,3)

While( KeyDown(KEY_ESCAPE)<>1 )   

 Local MXSpeed:Float = MouseXSpeed() 
 Local MYSpeed:Float = MouseYSpeed()   
 MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2) 
 PlayerEyesPitch = PlayerEyesPitch+MYSpeed*0.1
 If(PlayerEyesPitch > 89)
  PlayerEyesPitch = 89
 EndIf
 If(PlayerEyesPitch < -89)
  PlayerEyesPitch = -89
 EndIf
 PlayerColliderYaw = PlayerColliderYaw-MXSpeed*0.1   
 RotateEntity(PlayerEyes,PlayerEyesPitch,0,0)
 RotateEntity(PlayerCollider,0,PlayerColliderYaw,0)   

 Local CollidedCollidable:TEntity = EntityCollided(PlayerCollider,GroupEnvironment)
If( Not CollidedCollidable )
  PlayerIsOnGround = False
 Else'If( CollidedCollidable <> 0 )
  PlayerIsOnGround = True
 EndIf

 If( PlayerIsOnGround = False )
  'PlayerVY = PlayerVY - 0.0025
  TranslateEntity(PlayerCollider,PlayerVX,PlayerVY,PlayerVZ) 
  If(KeyDown(KEY_W)>0)
   MoveEntity(PlayerCollider,0,0,0.01) 
  Else If(KeyDown(KEY_A)>0) 
   MoveEntity(PlayerCollider,0,0,-0.01) 
  EndIf 
  If(KeyDown(KEY_S)>0) 
   MoveEntity(PlayerCollider,-0.01,0,0) 
  Else If(KeyDown(KEY_D)>0) 
   MoveEntity(PlayerCollider,0.01,0,0) 
  EndIf
 ElseIf( PlayerIsOnGround = True )
  PlayerOldX = EntityX(PlayerCollider,True)
  PlayerOldZ = EntityZ(PlayerCollider,True)
  PlayerVY = 0 
  If(KeyDown(1)>0)
   MoveEntity(PlayerCollider,0,0,0.1) 
  Else If(KeyDown(31)>0) 
   MoveEntity(PlayerCollider,0,0,-0.1) 
  EndIf 
  If(KeyDown(2)>0) 
   MoveEntity(PlayerCollider,-0.1,0,0) 
  Else If(KeyDown(32)>0) 
   MoveEntity(PlayerCollider,0.1,0,0) 
  EndIf 
  If(KeyDown(KEY_SPACE)>0)
   PlayerVY# = 0.1
  EndIf
  PlayerNewX = EntityX(PlayerCollider,True)
  PlayerNewZ = EntityZ(PlayerCollider,True)
  PlayerVX = PlayerNewX - PlayerOldX
  PlayerVZ = PlayerNewZ - PlayerOldZ 
 EndIf

 UpdateWorld()

 If(KeyHit(KEY_TAB)>0)
  If( ViewMode = CFirstPerson )
   ViewMode = CThirdPerson
  ElseIf( ViewMode = CThirdPerson )
   ViewMode = CFirstPerson
  EndIf
 EndIf

 If( ViewMode = CFirstPerson )
  PositionEntity(Camera,EntityX(PlayerEyes,True),EntityY(PlayerEyes,True),EntityZ(PlayerEyes,True))
  RotateEntity(Camera,EntityPitch(PlayerEyes,True),EntityYaw(PlayerEyes,True),EntityRoll(PlayerEyes,True))
  MoveEntity(Camera,0,0,0.0)
 ElseIf( ViewMode = CThirdPerson )
  PositionEntity(Camera,EntityX(PlayerEyes,True),EntityY(PlayerEyes,True),EntityZ(PlayerEyes,True))
  RotateEntity(Camera,EntityPitch(PlayerEyes,True),EntityYaw(PlayerEyes,True),EntityRoll(PlayerEyes,True))
  MoveEntity(Camera,0,0,-3.0)
 EndIf

 If(KeyDown(2)>0) 
  Wireframe(True) 
 Else 
  Wireframe(False) 
 EndIf 

 'SetBuffer(BackBuffer())
 RenderWorld() 

 Flip(1) 

Wend

End


and the original code

Graphics3D(800,600,32,2) 
HidePointer() 
SeedRnd(MilliSecs()) 
Const CFirstPerson% = 1
Const CThirdPerson% = 2
Global ViewMode% = CFirstPerson
Const GroupEnvironment% = 1
Const GroupCharacters% = 2
Global Camera = CreateCamera() 
CameraRange(Camera,0.1,1000)
CameraClsColor(Camera,000,000,000)   
Origine = CreateCube() 
ScaleMesh(Origine,0.1/2,1000.0,0.1/2)
EntityColor(Origine,255,000,000)
EntityFX(Origine,1)
GroundMesh = CreateCube()
ScaleMesh(GroundMesh,100.0/2,0.1/2,100.0/2)
PositionMesh(GroundMesh,100.0/2,-0.1/2,100.0/2)
EntityColor(GroundMesh,000,125,000)
EntityType(GroundMesh,GroupEnvironment)
For i% = 1 To 100
 Width# = Rnd(0.5,5.0)
 Depth# = Width*(Rnd(0.5,1.5))
 Height# = Width/2
 RockMesh = CreateSphere(8)
 ScaleMesh(RockMesh,Width/2,Height/2,Depth/2)
 RotateMesh(RockMesh,0,Rnd(-180,180),0)
 PositionMesh(RockMesh,Rnd(2.5,100.0-2.5),0,Rnd(2.5,100.0-2.5))
 EntityColor(RockMesh,050,050,050)
 EntityType(RockMesh,GroupEnvironment)
Next
For i% = 1 To 100
 CrateMesh = CreateCube()
 ScaleMesh(CrateMesh,1.0/2,1.0/2,1.0/2)
 PositionMesh(CrateMesh,0,1.0/2,0)
 RotateMesh(CrateMesh,0,Rnd(-180,180),0)
 PositionMesh(CrateMesh,Rnd(0.5,100.0-0.5),0,Rnd(0.5,100.0-0.5))
 EntityColor(CrateMesh,100,075,050)
 EntityType(CrateMesh,GroupEnvironment)
Next
PlayerCollider = CreatePivot() 
PositionEntity(PlayerCollider,0,0,0) 
EntityRadius(PlayerCollider,0.25)
EntityType(PlayerCollider,GroupCharacters)
PlayerColliderMarqueur = CreateSphere(16) ;for debug only
ScaleMesh(PlayerColliderMarqueur,0.5/2,0.5/2,0.5/2)
PositionEntity(PlayerColliderMarqueur,EntityX(PlayerCollider,True),EntityY(PlayerCollider,True),EntityZ(PlayerCollider,True))
EntityParent(PlayerColliderMarqueur,PlayerCollider,True)
EntityColor(PlayerColliderMarqueur,255,255,255)
EntityAlpha(PlayerColliderMarqueur,0.25)
PlayerEyes = CreatePivot()
PositionEntity(PlayerEyes,EntityX(PlayerCollider,True),EntityY(PlayerCollider,True)+1.6-0.25,EntityZ(PlayerCollider,True)+0.25)
EntityParent(PlayerEyes,PlayerCollider,True)
PlayerEyesMarqueur = CreateCube() ;for debug only
ScaleMesh(PlayerEyesMarqueur,0.025/2,0.025/2,0.025/2)
PositionEntity(PlayerEyesMarqueur,EntityX(PlayerEyes,True),EntityY(PlayerEyes,True),EntityZ(PlayerEyes,True))
EntityParent(PlayerEyesMarqueur,PlayerEyes,True)
EntityColor(PlayerEyesMarqueur,000,000,255)
PlayerMesh = CreateCube() 
ScaleMesh(PlayerMesh,0.5/2,1.7/2,0.25/2) 
PositionMesh(PlayerMesh,0,1.7/2,0) 
EntityColor(PlayerMesh,000,000,125) 
PositionEntity(PlayerMesh,EntityX(PlayerCollider,True),EntityY(PlayerCollider,True)-0.25,EntityZ(PlayerCollider,True)) 
EntityParent(PlayerMesh,PlayerCollider,True) 
ViewMode = CFirstPerson
PositionEntity(PlayerCollider,5,0.25+0.01,5)
PlayerColliderYaw# = 0
PlayerEyesPitch# = 0
PlayerIsOnGround% = 0
PlayerVX# = 0
PlayerVZ# = 0
PlayerVY# = 0
PlayerOldX# = 0
PlayerOldZ# = 0
PlayerNewX# = 0
PlayerNewZ# = 0
DirectLight = CreateLight(1) 
LightColor(DirectLight,125,125,125) 
PositionEntity(DirectLight,0,128.0,-128.0) 
RotateEntity(DirectLight,45,0,0) 
AmbientLight(063,063,063)
Collisions(GroupCharacters,GroupEnvironment,2,3)
While( KeyDown(1)<>1 )   
 MXSpeed# = MouseXSpeed() 
 MYSpeed# = MouseYSpeed()   
 MoveMouse(GraphicsWidth()/2,GraphicsHeight()/2) 
 PlayerEyesPitch = PlayerEyesPitch+MYSpeed*0.1
 If(PlayerEyesPitch > 89)
  PlayerEyesPitch = 89
 EndIf
 If(PlayerEyesPitch < -89)
  PlayerEyesPitch = -89
 EndIf
 PlayerColliderYaw = PlayerColliderYaw-MXSpeed*0.1   
 RotateEntity(PlayerEyes,PlayerEyesPitch,0,0)
 RotateEntity(PlayerCollider,0,PlayerColliderYaw,0)   
 CollidedCollidable% = EntityCollided(PlayerCollider,GroupEnvironment)
 If( CollidedCollidable = 0 )
  PlayerIsOnGround = False
 ElseIf( CollidedCollidable <> 0 )
  PlayerIsOnGround = True
 EndIf
 If( PlayerIsOnGround = False )
  PlayerVY = PlayerVY - 0.0025
  TranslateEntity(PlayerCollider,PlayerVX,PlayerVY,PlayerVZ) 
  If(KeyDown(17)>0)
   MoveEntity(PlayerCollider,0,0,0.01) 
  Else If(KeyDown(31)>0) 
   MoveEntity(PlayerCollider,0,0,-0.01) 
  EndIf 
  If(KeyDown(30)>0) 
   MoveEntity(PlayerCollider,-0.01,0,0) 
  Else If(KeyDown(32)>0) 
   MoveEntity(PlayerCollider,0.01,0,0) 
  EndIf
 ElseIf( PlayerIsOnGround = True )
  PlayerOldX = EntityX(PlayerCollider,True)
  PlayerOldZ = EntityZ(PlayerCollider,True)
  PlayerVY = 0 
  If(KeyDown(17)>0)
   MoveEntity(PlayerCollider,0,0,0.1) 
  Else If(KeyDown(31)>0) 
   MoveEntity(PlayerCollider,0,0,-0.1) 
  EndIf 
  If(KeyDown(30)>0) 
   MoveEntity(PlayerCollider,-0.1,0,0) 
  Else If(KeyDown(32)>0) 
   MoveEntity(PlayerCollider,0.1,0,0) 
  EndIf 
  If(KeyDown(57)>0)
   PlayerVY# = 0.1
  EndIf
  PlayerNewX = EntityX(PlayerCollider,True)
  PlayerNewZ = EntityZ(PlayerCollider,True)
  PlayerVX = PlayerNewX - PlayerOldX
  PlayerVZ = PlayerNewZ - PlayerOldZ 
 EndIf
 UpdateWorld()
 If(KeyHit(15)>0)
  If( ViewMode = CFirstPerson )
   ViewMode = CThirdPerson
  ElseIf( ViewMode = CThirdPerson )
   ViewMode = CFirstPerson
  EndIf
 EndIf
 If( ViewMode = CFirstPerson )
  PositionEntity(Camera,EntityX(PlayerEyes,True),EntityY(PlayerEyes,True),EntityZ(PlayerEyes,True))
  RotateEntity(Camera,EntityPitch(PlayerEyes,True),EntityYaw(PlayerEyes,True),EntityRoll(PlayerEyes,True))
  MoveEntity(Camera,0,0,0.0)
 ElseIf( ViewMode = CThirdPerson )
  PositionEntity(Camera,EntityX(PlayerEyes,True),EntityY(PlayerEyes,True),EntityZ(PlayerEyes,True))
  RotateEntity(Camera,EntityPitch(PlayerEyes,True),EntityYaw(PlayerEyes,True),EntityRoll(PlayerEyes,True))
  MoveEntity(Camera,0,0,-3.0)
 EndIf
 If(KeyDown(2)>0) 
  WireFrame(True) 
 Else 
  WireFrame(False) 
 EndIf 
 SetBuffer(BackBuffer())
 RenderWorld() 
 Flip(1) 
Wend
End()

im still interested in oldschool app/gamedev