Camera Position priority?

i’m creating a 2.5D fighter, the camera script makes sure your camera is 2D right? the issue is, this positioning is overriding camera manipulation such as screen-shakes i’m attempting to do. i’m asking, is there a way to set priorities to camera movement? solutions other than priorities are welcome.


Ex.
priority of 2D camera is 1, screenshake priority is 2, making it override


Code used:

local player = game:GetService("Players").LocalPlayer
local camera = workspace.CurrentCamera
local runservice = game:GetService("RunService")

local character = player.Character or player.CharacterAdded:Wait()
camera.CameraType = Enum.CameraType.Scriptable
camera.FieldOfView = 47.5
local HRP = character:WaitForChild("HumanoidRootPart")

runservice.RenderStepped:Connect(function()
	local characterPos = HRP.Position
	camera.CFrame = CFrame.new(characterPos) * CFrame.new(0,0,30)
end)

thanks in advance!

Above is a great video on camera manipulation, and also goes into a method I like on acheiving camera shake.

The only case I can think where you want to “override” the camera is for cutscenes and similar things where you want to control the camera in a specific way. For camera shake, you can “add on” the shake onto the already existing camera CFrame (which is creating the 2D perspective).

The basic idea is that the camera has “trauma”, which decreases linearly over time, and camera shake is trauma sqaured or cubed, so exponential. It also uses perlin noise, so that the shake is “smoother”- overall a nicer experience for the player.

Each frame, you want to calculate the trauma. Here is the function, which comes from the video, but into Luau and for Roblox:

local function calculateTrauma(dt)
    local seed = math.random(0, 500)
    
    local transform = {
        (MAX_ANGLE * math.noise(seed, dt * FREQUENCY) * 2 - 1) * math.pow(trauma, 2),
        (MAX_ANGLE * math.noise(seed + 1, dt * FREQUENCY) * 2 - 1) * math.pow(trauma, 2),
        (MAX_ANGLE * math.noise(seed + 2, dt * FREQUENCY) * 2 - 1) * math.pow(trauma, 2),
    }

    trauma = math.clamp(trauma - RECOVERY_SPEED * dt, 0, 1)
    
    local angle = CFrame.fromEulerAnglesXYZ(math.rad(transform[1]), math.rad(transform[2]), math.rad(transform[3]))

    camera.CFrame *= angle
end

FREQUENCY, RECOVERY_SPEED, and MAX_ANGLE are just some values, and it’s explained in the video. You can play around with these values, but I think these work well to start off with:

local FREQUENCY = 75
local RECOVERY_SPEED = 1.5
local MAX_ANGLE = 2

trauma keeps track of the current trauma, and when it’s initialised it’s set to 0.

local trauma = 0

And then run this function every frame, passing in delta time as the argument.

RunService.RenderStepped:Connect(function(dt) -- will be deprecated soon!
    calculateTrauma(dt)
end)

Whenever you want to “induce stress” on the camera i.e. make the camera shake, you can have some function to add trauma which will clamp the amount of stress you can add to 1, so it’s not an unbearable amount of shaking, like so:

local function addTrauma(stress)
    trauma = math.clamp(trauma + stress, 0, 1)
end

Hope this helps. Take a look at the video and it should explain more in detail. :slightly_smiling_face:

1 Like