WellDoneSnake
Yoko Shimomura
Heyo, I started working on completing a Dynamic 2D script I made a about year ago (prior to 2.2).
There are two types of camera modes I set up in this script and one of them which includes a camera sensitive to the player's speed has a weird viewing affect.
Large GIFs below:
This is how the camera should normally function, when the player is moving above their "runspeed" value in a certain direction:
Same is shown here when not controlling the player's movements directly:
However, I found this little oddity when I was experimenting with being moved something (like a horizontal/diagonal spring or booster):
If I'm holding onto the right key to try and move right while being launched in the opposite direction, the camera doesn't move to the left to show what's ahead of the player as intended.
I was able to replicate this issue with other spring items that move you horizontally at a certain speed.
Also this problem doesn't occur when holding onto the left key to try and move left while being launched in the opposite direction.
Oddly enough the camera problem is resolved when you keep pressing or holding the left key to face or move in the direction you're being launched in:
I've posted the script below, I should also note that this problem existed before the addition of the other camera 2D mode defined in the script below.
One more thing to note is that using print checks I found out that this section near the top of the script is not run when I performed the actions described earlier that lead to the camera issue:
There are two types of camera modes I set up in this script and one of them which includes a camera sensitive to the player's speed has a weird viewing affect.
Large GIFs below:
This is how the camera should normally function, when the player is moving above their "runspeed" value in a certain direction:
Same is shown here when not controlling the player's movements directly:
However, I found this little oddity when I was experimenting with being moved something (like a horizontal/diagonal spring or booster):
If I'm holding onto the right key to try and move right while being launched in the opposite direction, the camera doesn't move to the left to show what's ahead of the player as intended.
I was able to replicate this issue with other spring items that move you horizontally at a certain speed.
Also this problem doesn't occur when holding onto the left key to try and move left while being launched in the opposite direction.
Oddly enough the camera problem is resolved when you keep pressing or holding the left key to face or move in the direction you're being launched in:
I've posted the script below, I should also note that this problem existed before the addition of the other camera 2D mode defined in the script below.
One more thing to note is that using print checks I found out that this section near the top of the script is not run when I performed the actions described earlier that lead to the camera issue:
Code:
elseif mo.angle == ANGLE_180 or mo.angle == 0 and mo.x < mo.prevx
mo.an = $-FRACUNIT/2
if mo.an < -45*FRACUNIT/2
mo.an = -45*FRACUNIT/2
end
end
Code:
//Dynamic 2D Camera Script - By WellDoneSnake
/*Credits:
- Cosmos for informing me of how "player.awayviewtics" works.
- DylanDude for informing me of floorheight and ceilingheight affects on level
design.*/
freeslot("MT_2DCAMERA")
mobjinfo[MT_2DCAMERA] = {
doomednum = -1,
spawnstate = S_INVISIBLE,
spawnhealth = 1,
radius = 16*FRACUNIT,
height = 48*FRACUNIT,
flags = MF_NOGRAVITY|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT
}
addHook("PlayerSpawn", function(player)
local mo = player.mo
mo.Dyanmic2D = false
if mo.flags2 & MF2_TWOD
mo.flags2 = $^^MF2_TWOD
end
end)
addHook("PlayerThink", function(player)
local mo = player.mo
local cam = player.awayviewmobj
//===========Player 2D Camera Movement===========
if mo.Dynamic2D
player.awayviewtics = 2
//If the following is true, switch to a speed sensitive 2D camera,
//otherwise default to the standard dynamic 2D camera.
if mo.cameramove
//Speed sensitive camera's angle settings
if player.speed > player.runspeed or mo.eflags & MFE_SPRUNG
if mo.angle == 0 or mo.angle == ANGLE_180 and mo.x > mo.prevx
mo.an = $+FRACUNIT/2
if mo.an > 45*FRACUNIT/2
mo.an = 45*FRACUNIT/2
end
elseif mo.angle == ANGLE_180 or mo.angle == 0 and mo.x < mo.prevx
mo.an = $-FRACUNIT/2
if mo.an < -45*FRACUNIT/2
mo.an = -45*FRACUNIT/2
end
end
else
//Camera angle resets when below runspeed value
if mo.an > 0
mo.an = $-FRACUNIT/2
elseif mo.an < 0
mo.an = $+FRACUNIT/2
end
end
else
//Reset Camera Angle
if mo.an > 0
mo.an = $-FRACUNIT/2
elseif mo.an < 0
mo.an = $+FRACUNIT/2
end
end
//Checks for whether the player should be facing a certain direction
//at the speed they're moving.
local an = FixedAngle(mo.an)
if mo.angle == 0 and mo.x > mo.prevx
or mo.angle == ANGLE_180 and mo.x > mo.prevx
mo.movecameraright = true
mo.movecameraleft = false
elseif mo.angle == ANGLE_180 and mo.x < mo.prevx
or mo.angle == 0 and mo.x < mo.prevx
mo.movecameraleft = true
mo.movecameraright = false
end
//Camera Distance Checks
if mo.increasedistance
mo.distance = $+mo.distanceadjust
if mo.distance > mo.setdistance
mo.distance = mo.setdistance
mo.increasedistance = false
end
end
if mo.decreasedistance
mo.distance = $-mo.distanceadjust
if mo.distance < mo.setdistance
mo.distance = mo.setdistance
mo.decreasedistance = false
end
end
//Camera Angle Checks
if mo.increaseangle
mo.dangle = $+mo.angleadjust
if mo.dangle > mo.setdangle
mo.dangle = mo.setdangle
mo.increaseangle = false
end
end
if mo.decreaseangle
mo.dangle = $-mo.angleadjust
if mo.dangle < mo.setdangle
mo.dangle = mo.setdangle
mo.decreaseangle = false
end
end
//Position camera appropriately depending on the direction the player is facing.
//Note: also affected by the player's speed if "mo.cameramove" returns true.
if mo.movecameraright
cam.xpos = mo.x+mo.momx+FixedMul(mo.distance+(mo.an*2), cos(mo.dangle+an))
cam.ypos = mo.y+mo.momy+FixedMul(mo.distance+(mo.an*2), sin(mo.dangle+an))
cam.angle = R_PointToAngle2(cam.x, cam.y, mo.x, mo.y)-an
elseif mo.movecameraleft
cam.xpos = mo.x+mo.momx+FixedMul(mo.distance-(mo.an*2), cos(mo.dangle+an))
cam.ypos = mo.y+mo.momy+FixedMul(mo.distance-(mo.an*2), sin(mo.dangle+an))
cam.angle = R_PointToAngle2(cam.x, cam.y, mo.x, mo.y)-an
end
//Set timer to store player's previous x position in "mo.prevx" variable.
if mo.prevtimer == nil
mo.prevtimer = 2
elseif mo.prevtimer > 0
mo.prevtimer = $-1
elseif mo.prevtimer == 0
mo.prevx = mo.x
mo.prevtimer = 2
end
P_TeleportMove(cam, cam.xpos, cam.ypos, mo.z+48*FRACUNIT)
end
end)
local function TWODPlus(line, mo)
local sector = line.frontsector
local side = line.frontside
local player = mo.player
if not (mo.Dynamic2D) or mo.Dynamic2D and not (line.flags & ML_BLOCKMONSTERS)
//If "Slope Skew" and "Not Climbable" flags return false, a default
//distance and angle will be set for the camera.
if not (line.flags & ML_EFFECT1)
mo.setdistance = 400*FRACUNIT
end
if not (line.flags & ML_NOCLIMB)
mo.setdangle = -ANGLE_90
end
if line.flags & ML_EFFECT1 -- Slope Skew
mo.setdistance = side.textureoffset -- x texture offset sets camera distance
end
if line.flags & ML_NOCLIMB -- Check this flag to alter camera angle
mo.setdangle = -FixedAngle(side.rowoffset) -- y texture offset sets camera angle
end
if line.flags & ML_EFFECT2 -- No Midtexture Skew: sets the speed sensitive camera function if true
mo.cameramove = true
else
mo.cameramove = false
end
//Determine whether to adjust the camera's distance from the player.
if mo.distance != nil
if mo.distance > mo.setdistance
mo.decreasedistance = true
mo.increasedistance = false
elseif mo.distance < mo.setdistance
mo.increasedistance = true
mo.decreasedistance = false
end
end
//Determine whether to adjust the camera's angle in relation to the player.
if mo.dangle != nil
if mo.dangle > mo.setdangle
mo.decreaseangle = true
mo.increaseangle = false
elseif mo.dangle < mo.setdangle
mo.increaseangle = true
mo.decreaseangle = false
end
end
//Speed of camera distance adjustment.
//Note: cannot exceed below FRACUNIT or above 10*FRACUNIT.
if sector.floorheight > 10*FRACUNIT
mo.distanceadjust = 10*FRACUNIT
elseif sector.floorheight < FRACUNIT
mo.distanceadjust = FRACUNIT
else
mo.distanceadjust = sector.floorheight
end
//Speed of camera angle adjustment.
//Note: cannot exceed below 2 degrees or above 10 degrees.
if sector.ceilingheight > 10*FRACUNIT
mo.angleadjust = ANG10
elseif sector.ceilingheight < 2*FRACUNIT
mo.angleadjust = ANG2
else
mo.angleadjust = FixedAngle(sector.ceilingheight)
end
print(mo.setdangle)
//Extra Note: For decent camera adjustment speeds set both heights to 4.
end
if not (mo.Dynamic2D) and not (line.flags & ML_BLOCKMONSTERS)
mo.an = 0
mo.distance = mo.setdistance
mo.dangle = mo.setdangle
mo.flags2 = $^^MF2_TWOD
player.awayviewtics = 2
player.awayviewmobj = P_SpawnMobj(mo.x, mo.y, mo.z, MT_2DCAMERA)
mo.movecameraright = true
mo.Dynamic2D = true
end
//Exit 2D Mode if "Block Enemies" flags is checked.
if mo.Dynamic2D and line.flags & ML_BLOCKMONSTERS
mo.flags2 = $^^MF2_TWOD
mo.Dynamic2D = false
end
end
addHook("LinedefExecute", TWODPlus, "P_2DPLUS")