This tutorial is based on the Game Maker Studio GML, or
Game Maker Language. The language may differ from
whichever language you are coding in but the methods
can easily be adapted to your programming needs.
For Dead By Daylight I needed to make a camera system that would look good, function smoothly, and enhance gameplay. The system needed to accept up to four players on the screen at a time who could be anywhere relative to eachother. This meant that I would need a camera system that checked each players position and decided how far to zoom in and out, as well as adjust the view for movement throughout the level.
The camera movemnt also had to look good, and anyone who's handled camera movement code knows that means LERPing.
Finally, I had to add some method of camera shake for explosions and other effects.
Getting Started:
To begin create an object that the view will follow in the room. Typically a view will follow an object with a set speed and view border, or how far from the edge of the room to trigger view movement. Because we will be following up to four players at a time we couldn't just have the view follow a player and so we create a camera object. Also create your four player objects.
- Create an object: obj_camera
- Create an object: obj_player1
- Create an object: obj_player2
- Create an object: obj_player3
- Create an object: obj_player4
Leave the camera and players as is for now, we'll come back to them later.
Next you're going to want to open your room editor and open the VIEWS tab.
Check the boxes so that views are enabled, and view 0 is visible when the room starts.
View In Room refers to the area of the room that will be shown in View[0].
Port On Screen is the size of the window the view will occupy on the screen.
Object Following should be set to your camera object, obj_camera. This is what will stay
centered on the view.
We don't want any border around the camera so set it to 9999. We also want the view to
stay perfectly centered on the camera so set HSP and VSP to -1.
GAME MAKER STUDIO: Multiplayer Camera
-Part 1
Setting Up the Camera:
Open up your obj_camera and make an On Create Event. Enter the following code:
players = 4 //number of players to follow
p1x = 0 //hold players x/y positions
p1y = 0
p2x = 0
p2y = 0
p3x = 0
p3y = 0
p4x = 0
p4y = 0
largex = obj_player_p1 //hold largest and smallest positions to handle camera zoom
largey = obj_player_p1
smallx = obj_player_p1
smally = obj_player_p1
var_zoom = 1
hviewStart = view_hview[0] // zoom defaults
wviewStart = view_wview[0]
You have now given the camera everything it needs to begin determining the view position and zoom level it will need to follow 4 players. Next we will create the cameras STEP EVENT and add this code(It's a lot but follow along in the comments):
if players >= 2 //Skips the camera zoom code for 1 player
{
if players == 2
{
p1x = obj_player_p1.x // gather x/y positions for 2 players mode
p1y = obj_player_p1.y
p2x = obj_player_2.x
p2y = obj_player_2.y
if p1x > p2x {largex = obj_player_p1} //determine lowest x/y and highest x/y for 2 players mode
else if p2x > p1x {largex = obj_player_2} //also setting variable largex/y/smallx/y to the player fathest away
if p1x < p2x {smallx = obj_player_p1}
else if p2x < p1x {smallx = obj_player_2}
if p1y > p2y {largey = obj_player_p1}
else if p2y > p1y {largey = obj_player_2}
if p1y < p2y {smally = obj_player_p1}
else if p2y < p1y {smally = obj_player_2}
}
if players == 3
{
p1x = obj_player_p1.x // gather x/y positions for 3 players mode
p1y = obj_player_p1.y
p2x = obj_player_2.x
p2y = obj_player_2.y
p3x = obj_player_3.x
p3y = obj_player_3.y
if p1x > p2x and p1x > p3x{largex = obj_player_p1} //determine lowest x/y and highest x/y for 3 players mode
else if p2x > p1x and p2x > p3x{largex = obj_player_2}//variable largex/y/smallx/y to the player fathest away
else if p3x > p1x and p3x > p2x{largex = obj_player_3}
if p1x < p2x and p1x < p3x{smallx = obj_player_p1}
else if p2x < p1x and p2x < p3x {smallx = obj_player_2}
else if p3x < p1x and p3x < p2x {smallx = obj_player_3}
if p1y > p2y and p1y > p3y {largey = obj_player_p1}
else if p2y > p1y and p2y > p3y{largey = obj_player_2}
else if p3y > p1y and p3y > p2y{largey = obj_player_3}
if p1y < p2y and p1y < p3y {smally = obj_player_p1}
else if p2y < p1y and p2y < p3y {smally = obj_player_2}
else if p3y < p1y and p3y < p2y {smally = obj_player_3}
}
if players == 4
{
p1x = obj_player_p1.x // gather x/y positions for 4 players mode
p1y = obj_player_p1.y
p2x = obj_player_2.x
p2y = obj_player_2.y
p3x = obj_player_3.x
p3y = obj_player_3.y
p4x = obj_player_4.x
p4y = obj_player_4.y
if p1x > p2x and p1x > p3x and p1x > p4x{largex = obj_player_p1} //lowest x/y and highest x/y for 4 players mode
else if p2x > p1x and p2x > p3x and p2x > p4x{largex = obj_player_2}// largex/y/smallx/y to the player fathest away
else if p3x > p1x and p3x > p2x and p3x > p4x{largex = obj_player_3}
else if p4x > p1x and p4x > p3x and p4x > p2x{largex = obj_player_4}
if p1x < p2x and p1x < p3x and p1x < p4x{smallx = obj_player_p1}
else if p2x < p1x and p2x < p3x and p2x < p4x{smallx = obj_player_2}
else if p3x < p1x and p3x < p2x and p3x < p4x{smallx = obj_player_3}
else if p4x < p1x and p4x < p3x and p4x < p2x{smallx = obj_player_4}
if p1y > p2y and p1y > p3y and p1y > p4y{largey = obj_player_p1}
else if p2y > p1y and p2y > p3y and p2y > p4y{largey = obj_player_2}
else if p3y > p1y and p3y > p2y and p3y > p4y{largey = obj_player_3}
else if p4y > p1y and p4y > p3y and p4y > p2y{largey = obj_player_4}
if p1y < p2y and p1y < p3y and p1y < p4y{smally = obj_player_p1}
else if p2y < p1y and p2y < p3y and p2y < p4y{smally = obj_player_2}
else if p3y < p1y and p3y < p2y and p3y < p4y{smally = obj_player_3}
else if p4y < p1y and p4y < p3y and p4y < p2y{smally = obj_player_4}
}
distx = (largex.x - smallx.x); camPlayX = smallx.x //get distance between the farthest objects
disty = (largey.y - smally.y); camPlayY = smally.y //and tell camera which object to follow
dist12x = distx
dist12y = disty
if dist12x > 650 or dist12y > 650 //when the players get 650px apart begin to zoom out
{
if dist12x > dist12y{var_zoom = lerp(var_zoom,(dist12x * 0.0015),0.5)} //smooth zoom using LERP
else if dist12x < dist12y{var_zoom = lerp(var_zoom,(dist12y * 0.0015),0.5)}
view_hview[0] = floor(hviewStart * var_zoom) //adjust view to create zoom
view_wview[0] = floor(wviewStart * var_zoom)
}
else
{
view_hview[0] = hviewStart //zoom default
view_wview[0] = wviewStart
}
movex = (camPlayX)+ dist12x *0.5 //center the view from the smallest x/y object + half way to the farthest object
movey = (camPlayY)+ dist12y *0.5
dist = distance_to_point(movex,movey)
spd = lerp(0,dist,0.12)
move_towards_point(movex,movey,spd) //move the camera
}
else if players == 1 //simple camera movement with lerp, no zoom
{
movex = obj_player_p1.x
movey = obj_player_p1.y
dist = distance_to_point(movex,movey)
spd = lerp(0,dist,0.12)
move_towards_point(movex,movey,spd)
view_hview[0] = hviewStart
view_wview[0] = wviewStart
}
Add any sprite to the camera that you like so you can see the camera floating around and make sure it's working correctly.