Enhance built in camera function file

- Allows filters to be applied to custom cameras when running `startTempCam()`
- Automatically interpolates between cameras created in the same script
- Toggle to attempt to render the location if camera is far away from the ped
- Clears all created cameras when `stopTempCam()` is run
This commit is contained in:
Jim Shield
2025-09-05 16:34:45 +01:00
parent b35817740b
commit 2826bc95c7

View File

@@ -1,3 +1,5 @@
local camCache = {}
--- Creates a temporary camera at a specified position, pointing towards given coordinates.
--
-- This function creates a camera at a position relative to an entity or at a specified position and orients it to look at the target coordinates.
@@ -7,55 +9,120 @@
-- If `ent` is an entity, the camera position is calculated as an offset from the entity's position using `GetOffsetFromEntityInWorldCoords`.
-- If `ent` is a `vector3`, it is used directly as the camera's position.
--
---@param coords vector3 The target `vector3` coordinates that the camera will point at.
---@param coords vector3|entityId The target `vector3` coordinates that the camera will point at.
--
---@return cam camID The handle of the created camera, or `nil` if the camera was not created (e.g., if `Config.Crafting.craftCam` is `false`).
---@return camID number The handle of the created camera, or `nil` if the camera was not created (e.g., if `Config.Crafting.craftCam` is `false`).
--
---@usage
-- ```lua
-- local cam = createTempCam(entity, targetCoords)
-- ```
function createTempCam(ent, coords)
local cam = nil
if Config.Crafting.craftCam then
if debugMode then
triggerNotify(nil, "ModCam Created", "success")
end
local camID = nil
if Config.Crafting?.craftCam or Config.System.enableCam then
debugPrint("^6Bridge^7: ^2Custom Camera Created")
local camCoords = nil
local pointCoords = nil
if type(ent) ~= "vector3" then
camCoords = GetOffsetFromEntityInWorldCoords(ent, 1.0, -0.3, 0.8)
else
--local pointCoords = nil
if type(ent) ~= "number" then -- if received a vector3 or vector4 use those coords for origin point
camCoords = ent
end
cam = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", camCoords.x, camCoords.y, camCoords.z + 0.5, 1.0, 0.0, 0.0, 60.00, false, 0)
if type(coords) == "number" then
SetCamCoord(cam, GetCamCoord(cam) + vec3(0, 0, 1.0))
PointCamAtEntity(cam, coords)
else
PointCamAtCoord(cam, coords)
camCoords = GetOffsetFromEntityInWorldCoords(ent, 1.0, -0.3, 0.8)
end
-- Create the camera
camID = CreateCamWithParams("DEFAULT_SCRIPTED_CAMERA", camCoords.x, camCoords.y, camCoords.z + 0.5, 1.0, 0.0, 0.0, 60.00, false, 0)
camCache[#camCache+1] = camID
--if type(coords) == "number" then
-- SetCamCoord(camID, GetCamCoord(camID) + vec3(0, 0, 1.0))
--end
camLookAt(camID, coords)
end
return cam
return camID
end
local cacheCameraEffect = {}
local cachePrevCam = nil
--- Activates and starts rendering the temporary camera.
--
-- This function sets the specified camera as active and begins rendering it with a smooth transition.
-- The camera is only activated if `Config.Crafting.craftCam` is enabled in the configuration.
--
---@param cam camID The handle of the camera to activate and render.
---@param cam number The handle of the camera to activate and render.
---@param renderTime number The handle of the camera to activate and render.
---@param loadScene boolean The handle of the camera to activate and render.
---@param filter table The filter or postFx to render when starting the camera.
--
---@usage
-- ```lua
-- startTempCam(cam)
-- startTempCam(camID, 1000, true, { postFx = "HeistCelebEnd" })
-- ```
function startTempCam(cam)
if Config.Crafting.craftCam then
SetCamActive(cam, true)
RenderScriptCams(true, true, 1000, true, true)
function startTempCam(cam, renderTime, loadScene, filter)
if cam and DoesCamExist(cam) then
if cachePrevCam then
SetCamActiveWithInterp(cam, cachePrevCam, renderTime or 1000, 0, 0)
else
SetCamActive(cam, true)
end
cachePrevCam = cam
-- Clear previous filters
if cacheCameraEffect.postFx then
AnimpostfxStop(cacheCameraEffect.postFx)
cacheCameraEffect.postFx = nil
end
if cacheCameraEffect.timecycle then
ClearTimecycleModifier()
cacheCameraEffect.timecycle = nil
end
-- Apply filters (timecycle) here as requested
if filter and filter.modifier then
SetTimecycleModifier(filter.modifier)
SetTimecycleModifierStrength((filter.strength or 1.0) + 0.0)
cacheCameraEffect.timecycle = true
end
if filter and filter.postFx then
AnimpostfxPlay(filter.postFx, 0, filter.loop and true or false)
cacheCameraEffect.postFx = filter.postFx
end
if loadScene then
local pos = GetCamCoord(cam)
local radius = 100.0
SetFocusPosAndVel(pos.x, pos.y, pos.z, 0.0, 0.0, 0.0)
RequestCollisionAtCoord(pos.x, pos.y, pos.z)
NewLoadSceneStart(pos.x, pos.y, pos.z, 0.0, 0.0, 0.0, radius, 0)
local t0 = GetGameTimer()
while not IsNewLoadSceneLoaded() and (GetGameTimer() - t0) < 2000 do
RequestCollisionAtCoord(pos.x, pos.y, pos.z)
Wait(0)
end
NewLoadSceneStop()
end
RenderScriptCams(true, true, renderTime or 1000, true, true)
end
end
-- Follow cam or coords
function camLookAt(cam, entCoords)
if cam and entCoords then
if type(entCoords) ~= "number" then
PointCamAtCoord(cam, entCoords.xyz)
else
PointCamAtEntity(cam, entCoords)
end
end
end
@@ -71,11 +138,28 @@ end
-- stopTempCam()
-- ```
function stopTempCam()
if Config.Crafting.craftCam then
CreateThread(function()
Wait(1000)
RenderScriptCams(false, true, 500, true, true)
DestroyAllCams()
end)
end
CreateThread(function()
Wait(1000)
cachePrevCam = nil
-- Clear previous filters
if cacheCameraEffect.postFx then
AnimpostfxStop(cacheCameraEffect.postFx)
cacheCameraEffect.postFx = nil
end
if cacheCameraEffect.timecycle then
ClearTimecycleModifier()
cacheCameraEffect.timecycle = nil
end
RenderScriptCams(false, true, 500, true, true)
for i = 1, #camCache do
DestroyCam(camCache[i], true)
end
camCache = {}
--DestroyAllCams()
ClearFocus()
NewLoadSceneStop()
end)
end