Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save pinguluk/3e1cd20f50dec3c5e4e4c3addc3eb711 to your computer and use it in GitHub Desktop.
Save pinguluk/3e1cd20f50dec3c5e4e4c3addc3eb711 to your computer and use it in GitHub Desktop.
This is a fix/patch for First Person AND Customizable Cameras (With UI) mod (CustomizableCamera(WithUI) V4.0 to be more specific) for Hogwarts Legacy from https://www.nexusmods.com/hogwartslegacy/mods/869

About

This is a fix/patch for First Person AND Customizable Cameras (With UI) mod (CustomizableCamera(WithUI) V4.0 to be more specific) for Hogwarts Legacy from https://www.nexusmods.com/hogwartslegacy/mods/869

The problems I've fixed

There are two problems:

  1. The mod isn't initialised (the UI works, but nothing happens when you change the settings);
  2. When the mod it's actually initialised at some point, it will stop working after the player uses fast travel or when it dies.

The first problem is caused by the function

NotifyOnNewObject("/Script/Phoenix.Loadingcreen", function(self)
	currentScreen = self
	delayTrigger = 10000
	canTrigger = true
end)

that doesn't trigger for some reasons,

thus from

RegisterHook("/Script/Engine.PlayerController:ClientRestart", function(Context, NewPawn)
	
	print("Hooked on load / reload succesfully - CameraUI Mod\n")
	
	if funcHooked then
		ExecuteWithDelay(delayTrigger, repairCrashFix2nd)
	end
	
	if funcHooked == false then
		if canTrigger then
			ExecuteWithDelay(delayTrigger, repairCrashFix)
			canTrigger = false
		end
	end
	
end)

the funcHooked and canTrigger variables will be always false => the repairCrashFix functions won't trigger (mod won't be initialised).

The second problem comes from this function:

RegisterHook("/Script/Engine.PlayerController:ClientRestart", function(Context, NewPawn)
	
	print("Hooked on load / reload succesfully - CameraUI Mod\n")
	
	if funcHooked then
		ExecuteWithDelay(delayTrigger, repairCrashFix2nd)
	end
	
	if funcHooked == false then
		if canTrigger then
			ExecuteWithDelay(delayTrigger, repairCrashFix)
			canTrigger = false
		end
	end
	
end)

When you fast travel or die, the objects (player, cameras, environment etc) are basically being destroyed and respawned. The

RegisterHook("/Script/Engine.PlayerController:ClientRestart"

hook doesn't account that the objects are being destroyed and respawned, therefore the mod won't be reinitialised again.

How does my fix works

Instead on relaying on

NotifyOnNewObject("/Script/Phoenix.Loadingcreen"

and

RegisterHook("/Script/Engine.PlayerController:ClientRestart"

hooks, it will be relaying on

RegisterHook("/Script/Phoenix.Biped_Player:OnCharacterLoadComplete",

hook, which is triggered everytime our character is loaded => mod will be (re)initialised everytime => mod functions will be working (again)

What has been changed

I've deleted the code that will no longer be used, so this

NotifyOnNewObject("/Script/Phoenix.Loadingcreen", function(self)
	currentScreen = self
	delayTrigger = 10000
	canTrigger = true
end)

function repairCrashFix()
	if currentScreen ~= nil or not currentScreen:IsValid() then
		print("CameraUIW created\n")
		fetchCameras()
		if currentCam == "firstperson" then
			retrieveFpsCameras()
			setCharacterInFPSView()
		end
		HookCameraUI()
		loadCameraSettings()
	else
		ExecuteWithDelay(1000, repairCrashFix)
		return
	end
end

function repairCrashFix2nd()
	print("CameraUIW RE-Created\n")
	fetchCameras()
	if currentCam == "firstperson" then
		retrieveFpsCameras()
		setCharacterInFPSView()
	end
	HookCameraUI()
	loadCameraSettings()
end

RegisterHook("/Script/Engine.PlayerController:ClientRestart", function(Context, NewPawn)
	
	print("Hooked on load / reload succesfully - CameraUI Mod\n")
	
	if funcHooked then
		ExecuteWithDelay(delayTrigger, repairCrashFix2nd)
	end
	
	if funcHooked == false then
		if canTrigger then
			ExecuteWithDelay(delayTrigger, repairCrashFix)
			canTrigger = false
		end
	end
	
end)

will become only this

RegisterHook("/Script/Phoenix.Biped_Player:OnCharacterLoadComplete", function(self)
    print("CameraUIW RE-Created\n")
    fetchCameras()
    if currentCam == "firstperson" then
        retrieveFpsCameras()
        setCharacterInFPSView()
    end
    HookCameraUI()
    loadCameraSettings()
end)

How to apply the fix

You can download the already changed file with the fix from below (Right click on the Raw button from main.lua and save it to your PC, by clicking Save link as...) and then replace it in *\Hogwarts Legacy\Phoenix\Binaries\Win64\Mods\TestCameraOffset\scripts.

(or you can edit the file manually yourself and apply the patch/fix, but I don't see why would you do that)

Also I recommend you to update the RE-UE4SS tool with the latest version (you can use the one from Nexus Mods website directly https://www.nexusmods.com/hogwartslegacy/mods/942, instead of downloading it from GitHub repo)

local Json = require("jsonStorage")
local UEHelpers = require("UEHelpers")
local ver = "3.2-FRelease"
local cameraConfig = 0
local currentCam = "indoor"
local allCams = {
["0"] = "indoor",
["1"] = "outdoor",
["2"] = "swimming",
["3"] = "broom",
["4"] = "aiming",
["5"] = "firstperson"
}
local allCamsForUI = {
["indoor"] = 0.0,
["outdoor"] = 1.0,
["swimming"] = 2.0,
["broom"] = 3.0,
["aiming"] = 4.0,
["firstperson"] = 5.0
}
local funcHooked = false
local canTrigger = false
local currentScreen = nil
local Glbl_InsideCameraStacks = nil
local Glbl_OpenSpaceCameraStacks = nil
local Glbl_SwimmingCameraStacks = nil
local Glbl_BroomCameraStacks = nil
local Glbl_AimingCameraStacks = nil
local Glbl_CameraStackBehaviorCollisionPrediction = nil
local Glbl_BP_PitchToTransformCurves_Default_C = nil
local Glbl_BP_AmbientCamAnim_Idle_C = nil
local Glbl_BP_AmbientCamAnim_Jog_C = nil
local cameraOffsetsSettings = {
["indoor"] = {
["X"] = 0,
["Y"] = 0,
["Z"] = 0
},
["outdoor"] = {
["X"] = 0,
["Y"] = 0,
["Z"] = 0
},
["swimming"] = {
["X"] = 0,
["Y"] = 0,
["Z"] = 0
},
["broom"] = {
["X"] = 0,
["Y"] = 0,
["Z"] = 0
},
["aiming"] = {
["X"] = 0,
["Y"] = 0,
["Z"] = 0
}
}
local bNeedsReloading = true
local reloaders = {
["CameraOffsetX"] = false,
["CameraOffsetY"] = false,
["CameraOffsetZ"] = false,
["CameraConfig"] = false,
["CameraName"] = false
}
function fif(condition, if_true, if_false)
if condition then
return if_true
else
return if_false
end
end
function GetPlayerController()
local PlayerControllers = FindAllOf("PlayerController")
local PlayerController = nil
for Index, Controller in pairs(PlayerControllers) do
if Controller.Pawn:IsValid() and Controller.Pawn:IsPlayerControlled() then
return Controller
end
end
end
--[[ function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
if raw then return s end
s = string.gsub(s, '^%s+', '')
s = string.gsub(s, '%s+$', '')
s = string.gsub(s, '[\n\r]+', ' ')
return s
end ]] --
function fetchCameras()
Glbl_InsideCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Default_C")
Glbl_OpenSpaceCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_OpenSpace_C")
Glbl_SwimmingCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Swimming_OpenSpace_C")
Glbl_BroomCameraStacks = FindAllOf("DA_NewBroomFlightCamera_StackSettings")
Glbl_AimingCameraStacks = FindAllOf("DA_AimCamera_StackSettings")
end
function retryFetchingCameras()
if Glbl_InsideCameraStacks == nil then
Glbl_InsideCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Default_C")
end
if Glbl_OpenSpaceCameraStacks == nil then
Glbl_OpenSpaceCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_OpenSpace_C")
end
if Glbl_SwimmingCameraStacks == nil then
Glbl_SwimmingCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Swimming_OpenSpace_C")
end
if Glbl_BroomCameraStacks == nil then
Glbl_BroomCameraStacks = FindAllOf("DA_NewBroomFlightCamera_StackSettings")
end
if Glbl_AimingCameraStacks == nil then
Glbl_AimingCameraStacks = FindAllOf("DA_AimCamera_StackSettings")
end
end
function setGlblCameraStack()
if Glbl_InsideCameraStacks ~= nil then
for Index, Stack in pairs(Glbl_InsideCameraStacks) do
if Stack:IsValid() then
Stack:SetPropertyValue("CameraSpaceTranslation", {
["X"] = cameraOffsetsSettings["indoor"].X,
["Y"] = cameraOffsetsSettings["indoor"].Y,
["Z"] = cameraOffsetsSettings["indoor"].Z
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_OpenSpaceCameraStacks ~= nil then
for Index, Stack in pairs(Glbl_OpenSpaceCameraStacks) do
if Stack:IsValid() then
Stack:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (-95 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["outdoor"].X,
["Y"] = (20 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["outdoor"].Y,
["Z"] = (-35 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["outdoor"].Z
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_SwimmingCameraStacks ~= nil then
for Index, Stack in pairs(Glbl_SwimmingCameraStacks) do
if Stack:IsValid() then
Stack:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (-200 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["swimming"].X,
["Y"] = (0 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["swimming"].Y,
["Z"] = (50 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["swimming"].Z
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BroomCameraStacks ~= nil then
for Index, Stack in pairs(Glbl_BroomCameraStacks) do
if Stack:IsValid() then
Stack.CameraStackBehaviorAddCameraSpaceTranslation_0:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (0 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["broom"].X,
["Y"] = (40 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["broom"].Y,
["Z"] = (0 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["broom"].Z
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_AimingCameraStacks ~= nil then
for Index, Stack in pairs(Glbl_AimingCameraStacks) do
if Stack:IsValid() then
Stack.CameraStackBehaviorAddCameraSpaceTranslation_0:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (0 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["aiming"].X,
["Y"] = (20 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["aiming"].Y,
["Z"] = (0 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["aiming"].Z
})
else
print("Not valid CameraStack\n")
end
end
end
ExecuteWithDelay(5000, retryFetchingCameras)
end
function saveSettings()
local currentSavedValues = {}
if currentCam ~= "firstperson" then
currentSavedValues = cameraOffsetsSettings[currentCam]
end
Json.saveTable(currentSavedValues, "CameraSettings.json", string.format("%s_config %s", currentCam, cameraConfig))
Json.saveTable(cameraConfig, "Settings.json", "lastUsedConfig")
Json.saveTable(currentCam, "Settings.json", "lastEditedCamera")
end
function loadCameraSettings()
local indoorCamSettings = Json.loadTable("CameraSettings.json", string.format("indoor_config %s", cameraConfig))
cameraOffsetsSettings["indoor"] = indoorCamSettings
local outdoorCamSettings = Json.loadTable("CameraSettings.json", string.format("outdoor_config %s", cameraConfig))
cameraOffsetsSettings["outdoor"] = outdoorCamSettings
local swimmingOutdoorCamSettings = Json.loadTable("CameraSettings.json",
string.format("swimming_config %s", cameraConfig))
cameraOffsetsSettings["swimming"] = swimmingOutdoorCamSettings
local broomCamSettings = Json.loadTable("CameraSettings.json", string.format("broom_config %s", cameraConfig))
cameraOffsetsSettings["broom"] = broomCamSettings
local aimingCamSettings = Json.loadTable("CameraSettings.json", string.format("aiming_config %s", cameraConfig))
cameraOffsetsSettings["aiming"] = aimingCamSettings
bNeedsReloading = true
reloaders = {
["CameraOffsetX"] = false,
["CameraOffsetY"] = false,
["CameraOffsetZ"] = false,
["CameraConfig"] = false,
["CameraName"] = false
}
if currentCam ~= "firstperson" then
setGlblCameraStack()
end
end
function loadSettings()
cameraConfig = Json.loadTable("Settings.json", "lastUsedConfig")
currentCam = Json.loadTable("Settings.json", "lastEditedCamera")
loadCameraSettings()
end
function setCharacterInFPSView()
if Glbl_CameraStackBehaviorCollisionPrediction ~= nil then
for Index, Stack in pairs(Glbl_CameraStackBehaviorCollisionPrediction) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_PitchToTransformCurves_Default_C ~= nil then
for Index, Stack in pairs(Glbl_BP_PitchToTransformCurves_Default_C) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Idle_C ~= nil then
for Index, Stack in pairs(Glbl_BP_AmbientCamAnim_Idle_C) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Jog_C ~= nil then
for Index, Stack in pairs(Glbl_BP_AmbientCamAnim_Jog_C) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_OpenSpaceCameraStacks ~= nil then
for Index, Stack in pairs(Glbl_OpenSpaceCameraStacks) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
end
function revertCharacterView()
if Glbl_CameraStackBehaviorCollisionPrediction ~= nil then
for Index, Stack in pairs(Glbl_CameraStackBehaviorCollisionPrediction) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_PitchToTransformCurves_Default_C ~= nil then
for Index, Stack in pairs(Glbl_BP_PitchToTransformCurves_Default_C) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Idle_C ~= nil then
for Index, Stack in pairs(Glbl_BP_AmbientCamAnim_Idle_C) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Jog_C ~= nil then
for Index, Stack in pairs(Glbl_BP_AmbientCamAnim_Jog_C) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_OpenSpaceCameraStacks ~= nil then
for Index, Stack in pairs(Glbl_OpenSpaceCameraStacks) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
end
RegisterHook("/Script/Phoenix.Biped_Player:OnCharacterLoadComplete", function(self)
print("CameraUIW RE-Created\n")
fetchCameras()
if currentCam == "firstperson" then
retrieveFpsCameras()
setCharacterInFPSView()
end
HookCameraUI()
loadCameraSettings()
end)
function HookCameraUI()
RegisterHook("/Game/CustomContent/UI/CameraUIW.CameraUIW_C:Tick", function(Context)
local CameraWidget = Context:get()
local bShouldSave = CameraWidget:GetPropertyValue("bSavePreset")
if bNeedsReloading and currentCam == "firstperson" then
CameraWidget:SetPropertyValue("UpdatedCameraName", allCamsForUI[currentCam])
CameraWidget:SetPropertyValue("bForceUpdate", true)
bNeedsReloading = false
end
if bNeedsReloading then
CameraWidget:SetPropertyValue("UpdatedValues", {
["X"] = cameraOffsetsSettings[currentCam].X,
["Y"] = cameraOffsetsSettings[currentCam].Y,
["Z"] = cameraOffsetsSettings[currentCam].Z
})
CameraWidget:SetPropertyValue("UpdatedCameraName", allCamsForUI[currentCam])
CameraWidget:SetPropertyValue("UpdatedCameraConfig", cameraConfig)
CameraWidget:SetPropertyValue("bForceUpdate", true)
bNeedsReloading = false
end
if bShouldSave then
saveSettings()
CameraWidget:SetPropertyValue("bSavePreset", false)
end
end)
RegisterHook("/Game/CustomContent/UI/CameraWigetSlate.CameraWigetSlate_C:Tick", function(Context)
local CameraOffsetWidget = Context:get()
if not CameraOffsetWidget:IsValid() then
print("CameraOffsetWidget is not valid.\n")
return
end
local name = CameraOffsetWidget:GetPropertyValue("Name")
name = name:ToString()
local CameraOffset = CameraOffsetWidget:GetPropertyValue("CameraOffset")
if funcHooked == false then
print("the func is hooked")
funcHooked = true
end
if bNeedsReloading == false then
if name == "CameraOffsetX" and currentCam ~= "firstperson" then
cameraOffsetsSettings[currentCam]["X"] = CameraOffset
elseif name == "CameraOffsetY" and currentCam ~= "firstperson" then
cameraOffsetsSettings[currentCam]["Y"] = CameraOffset
elseif name == "CameraOffsetZ" and currentCam ~= "firstperson" then
cameraOffsetsSettings[currentCam]["Z"] = CameraOffset
elseif name == "CameraConfig" and currentCam ~= "firstperson" then
local flooredOffset = math.floor(CameraOffset)
if cameraConfig ~= flooredOffset then
saveSettings()
cameraConfig = flooredOffset
loadCameraSettings()
end
elseif name == "CameraName" then
local flooredOffset = string.format("%s", math.floor(CameraOffset))
if currentCam ~= allCams[flooredOffset] and currentCam ~= "firstperson" then
saveSettings()
currentCam = fif(allCams[flooredOffset] == nil, currentCam, allCams[flooredOffset])
if currentCam == "firstperson" then
retrieveFpsCameras()
setCharacterInFPSView()
else
loadCameraSettings()
end
elseif currentCam == "firstperson" and currentCam ~= allCams[flooredOffset] then
Json.saveTable(currentCam, "Settings.json", "lastEditedCamera")
currentCam = allCams[flooredOffset]
revertCharacterView()
loadCameraSettings()
end
end
end
setGlblCameraStack()
end)
end
function retrieveFpsCameras()
Glbl_BP_PitchToTransformCurves_Default_C = FindAllOf("BP_PitchToTransformCurves_Default_C")
Glbl_BP_AmbientCamAnim_Idle_C = FindAllOf("BP_AmbientCamAnim_Idle_C")
Glbl_BP_AmbientCamAnim_Jog_C = FindAllOf("BP_AmbientCamAnim_Jog_C")
Glbl_CameraStackBehaviorCollisionPrediction = FindAllOf("CameraStackBehaviorCollisionPrediction")
end
local Json = require("jsonStorage")
local UEHelpers = require("UEHelpers")
local ver = "3.2-FRelease"
local cameraConfig = 0
local currentCam = "indoor"
local allCams = {["0"] = "indoor", ["1"] = "outdoor", ["2"] = "swimming", ["3"] = "broom", ["4"] = "aiming", ["5"] = "firstperson"}
local allCamsForUI = {["indoor"] = 0.0, ["outdoor"] = 1.0, ["swimming"] = 2.0, ["broom"] = 3.0, ["aiming"] = 4.0, ["firstperson"] = 5.0}
local funcHooked = false
local canTrigger = false
local currentScreen = nil
local Glbl_InsideCameraStacks = nil
local Glbl_OpenSpaceCameraStacks = nil
local Glbl_SwimmingCameraStacks = nil
local Glbl_BroomCameraStacks = nil
local Glbl_AimingCameraStacks = nil
local Glbl_CameraStackBehaviorCollisionPrediction = nil
local Glbl_BP_PitchToTransformCurves_Default_C = nil
local Glbl_BP_AmbientCamAnim_Idle_C = nil
local Glbl_BP_AmbientCamAnim_Jog_C = nil
local cameraOffsetsSettings = {
["indoor"] = {["X"] = 0, ["Y"] = 0, ["Z"] = 0},
["outdoor"] = {["X"] = 0, ["Y"] = 0, ["Z"] = 0},
["swimming"] = {["X"] = 0, ["Y"] = 0, ["Z"] = 0},
["broom"] = {["X"] = 0, ["Y"] = 0, ["Z"] = 0},
["aiming"] = {["X"] = 0, ["Y"] = 0, ["Z"] = 0}
}
local bNeedsReloading = true
local reloaders = {
["CameraOffsetX"] = false,
["CameraOffsetY"] = false,
["CameraOffsetZ"] = false,
["CameraConfig"] = false,
["CameraName"] = false
}
function fif(condition, if_true, if_false)
if condition then return if_true else return if_false end
end
function GetPlayerController()
local PlayerControllers = FindAllOf("PlayerController")
local PlayerController = nil
for Index,Controller in pairs(PlayerControllers) do
if Controller.Pawn:IsValid() and Controller.Pawn:IsPlayerControlled() then
return Controller
end
end
end
--[[ function os.capture(cmd, raw)
local f = assert(io.popen(cmd, 'r'))
local s = assert(f:read('*a'))
f:close()
if raw then return s end
s = string.gsub(s, '^%s+', '')
s = string.gsub(s, '%s+$', '')
s = string.gsub(s, '[\n\r]+', ' ')
return s
end ]]--
function fetchCameras()
Glbl_InsideCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Default_C")
Glbl_OpenSpaceCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_OpenSpace_C")
Glbl_SwimmingCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Swimming_OpenSpace_C")
Glbl_BroomCameraStacks = FindAllOf("DA_NewBroomFlightCamera_StackSettings")
Glbl_AimingCameraStacks = FindAllOf("DA_AimCamera_StackSettings")
end
function retryFetchingCameras()
if Glbl_InsideCameraStacks == nil then Glbl_InsideCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Default_C") end
if Glbl_OpenSpaceCameraStacks == nil then Glbl_OpenSpaceCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_OpenSpace_C") end
if Glbl_SwimmingCameraStacks == nil then Glbl_SwimmingCameraStacks = FindAllOf("BP_AddCameraSpaceTranslation_Swimming_OpenSpace_C") end
if Glbl_BroomCameraStacks == nil then Glbl_BroomCameraStacks = FindAllOf("DA_NewBroomFlightCamera_StackSettings") end
if Glbl_AimingCameraStacks == nil then Glbl_AimingCameraStacks = FindAllOf("DA_AimCamera_StackSettings") end
end
function setGlblCameraStack()
if Glbl_InsideCameraStacks ~= nil then
for Index,Stack in pairs(Glbl_InsideCameraStacks) do
if Stack:IsValid() then
Stack:SetPropertyValue("CameraSpaceTranslation", {
["X"] = cameraOffsetsSettings["indoor"].X,
["Y"] = cameraOffsetsSettings["indoor"].Y,
["Z"] = cameraOffsetsSettings["indoor"].Z,
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_OpenSpaceCameraStacks ~= nil then
for Index,Stack in pairs(Glbl_OpenSpaceCameraStacks) do
if Stack:IsValid() then
Stack:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (-95 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["outdoor"].X,
["Y"] = (20 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["outdoor"].Y,
["Z"] = (-35 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["outdoor"].Z,
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_SwimmingCameraStacks ~= nil then
for Index,Stack in pairs(Glbl_SwimmingCameraStacks) do
if Stack:IsValid() then
Stack:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (-200 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["swimming"].X,
["Y"] = (0 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["swimming"].Y,
["Z"] = (50 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["swimming"].Z,
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BroomCameraStacks ~= nil then
for Index,Stack in pairs(Glbl_BroomCameraStacks) do
if Stack:IsValid() then
Stack.CameraStackBehaviorAddCameraSpaceTranslation_0:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (0 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["broom"].X,
["Y"] = (40 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["broom"].Y,
["Z"] = (0 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["broom"].Z,
})
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_AimingCameraStacks ~= nil then
for Index,Stack in pairs(Glbl_AimingCameraStacks) do
if Stack:IsValid() then
Stack.CameraStackBehaviorAddCameraSpaceTranslation_0:SetPropertyValue("CameraSpaceTranslation", {
["X"] = (0 + (cameraOffsetsSettings["indoor"].X * -1)) + cameraOffsetsSettings["aiming"].X,
["Y"] = (20 + (cameraOffsetsSettings["indoor"].Y * -1)) + cameraOffsetsSettings["aiming"].Y,
["Z"] = (0 + (cameraOffsetsSettings["indoor"].Z * -1)) + cameraOffsetsSettings["aiming"].Z,
})
else
print("Not valid CameraStack\n")
end
end
end
ExecuteWithDelay(5000, retryFetchingCameras)
end
function saveSettings()
local currentSavedValues = {}
if currentCam ~= "firstperson" then
currentSavedValues = cameraOffsetsSettings[currentCam]
end
Json.saveTable(currentSavedValues, "CameraSettings.json", string.format("%s_config %s", currentCam, cameraConfig))
Json.saveTable(cameraConfig, "Settings.json", "lastUsedConfig")
Json.saveTable(currentCam, "Settings.json", "lastEditedCamera")
end
function loadCameraSettings()
local indoorCamSettings = Json.loadTable("CameraSettings.json", string.format("indoor_config %s", cameraConfig))
cameraOffsetsSettings["indoor"] = indoorCamSettings
local outdoorCamSettings = Json.loadTable("CameraSettings.json", string.format("outdoor_config %s", cameraConfig))
cameraOffsetsSettings["outdoor"] = outdoorCamSettings
local swimmingOutdoorCamSettings = Json.loadTable("CameraSettings.json", string.format("swimming_config %s", cameraConfig))
cameraOffsetsSettings["swimming"] = swimmingOutdoorCamSettings
local broomCamSettings = Json.loadTable("CameraSettings.json", string.format("broom_config %s", cameraConfig))
cameraOffsetsSettings["broom"] = broomCamSettings
local aimingCamSettings = Json.loadTable("CameraSettings.json", string.format("aiming_config %s", cameraConfig))
cameraOffsetsSettings["aiming"] = aimingCamSettings
bNeedsReloading = true
reloaders = {
["CameraOffsetX"] = false,
["CameraOffsetY"] = false,
["CameraOffsetZ"] = false,
["CameraConfig"] = false,
["CameraName"] = false
}
if currentCam ~= "firstperson" then
setGlblCameraStack()
end
end
function loadSettings()
cameraConfig = Json.loadTable("Settings.json", "lastUsedConfig")
currentCam = Json.loadTable("Settings.json", "lastEditedCamera")
loadCameraSettings()
end
function setCharacterInFPSView()
if Glbl_CameraStackBehaviorCollisionPrediction ~= nil then
for Index,Stack in pairs(Glbl_CameraStackBehaviorCollisionPrediction) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_PitchToTransformCurves_Default_C ~= nil then
for Index,Stack in pairs(Glbl_BP_PitchToTransformCurves_Default_C) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Idle_C ~= nil then
for Index,Stack in pairs(Glbl_BP_AmbientCamAnim_Idle_C) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Jog_C ~= nil then
for Index,Stack in pairs(Glbl_BP_AmbientCamAnim_Jog_C) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_OpenSpaceCameraStacks ~= nil then
for Index,Stack in pairs(Glbl_OpenSpaceCameraStacks) do
if Stack:IsValid() then
Stack:SetDisabled(true, true)
else
print("Not valid CameraStack\n")
end
end
end
end
function revertCharacterView()
if Glbl_CameraStackBehaviorCollisionPrediction ~= nil then
for Index,Stack in pairs(Glbl_CameraStackBehaviorCollisionPrediction) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_PitchToTransformCurves_Default_C ~= nil then
for Index,Stack in pairs(Glbl_BP_PitchToTransformCurves_Default_C) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Idle_C ~= nil then
for Index,Stack in pairs(Glbl_BP_AmbientCamAnim_Idle_C) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_BP_AmbientCamAnim_Jog_C ~= nil then
for Index,Stack in pairs(Glbl_BP_AmbientCamAnim_Jog_C) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
if Glbl_OpenSpaceCameraStacks ~= nil then
for Index,Stack in pairs(Glbl_OpenSpaceCameraStacks) do
if Stack:IsValid() then
Stack:SetDisabled(false, true)
else
print("Not valid CameraStack\n")
end
end
end
end
NotifyOnNewObject("/Script/Phoenix.Loadingcreen", function(self)
currentScreen = self
delayTrigger = 10000
canTrigger = true
end)
function repairCrashFix()
if currentScreen ~= nil or not currentScreen:IsValid() then
print("CameraUIW created\n")
fetchCameras()
if currentCam == "firstperson" then
retrieveFpsCameras()
setCharacterInFPSView()
end
HookCameraUI()
loadCameraSettings()
else
ExecuteWithDelay(1000, repairCrashFix)
return
end
end
function repairCrashFix2nd()
print("CameraUIW RE-Created\n")
fetchCameras()
if currentCam == "firstperson" then
retrieveFpsCameras()
setCharacterInFPSView()
end
HookCameraUI()
loadCameraSettings()
end
RegisterHook("/Script/Engine.PlayerController:ClientRestart", function(Context, NewPawn)
print("Hooked on load / reload succesfully - CameraUI Mod\n")
if funcHooked then
ExecuteWithDelay(delayTrigger, repairCrashFix2nd)
end
if funcHooked == false then
if canTrigger then
ExecuteWithDelay(delayTrigger, repairCrashFix)
canTrigger = false
end
end
end)
function HookCameraUI()
RegisterHook("/Game/CustomContent/UI/CameraUIW.CameraUIW_C:Tick", function(Context)
local CameraWidget = Context:get()
local bShouldSave = CameraWidget:GetPropertyValue("bSavePreset")
if bNeedsReloading and currentCam == "firstperson" then
CameraWidget:SetPropertyValue("UpdatedCameraName", allCamsForUI[currentCam])
CameraWidget:SetPropertyValue("bForceUpdate", true)
bNeedsReloading = false
end
if bNeedsReloading then
CameraWidget:SetPropertyValue("UpdatedValues", { ["X"] = cameraOffsetsSettings[currentCam].X, ["Y"] = cameraOffsetsSettings[currentCam].Y, ["Z"] = cameraOffsetsSettings[currentCam].Z})
CameraWidget:SetPropertyValue("UpdatedCameraName", allCamsForUI[currentCam])
CameraWidget:SetPropertyValue("UpdatedCameraConfig", cameraConfig)
CameraWidget:SetPropertyValue("bForceUpdate", true)
bNeedsReloading = false
end
if bShouldSave then
saveSettings()
CameraWidget:SetPropertyValue("bSavePreset", false)
end
end)
RegisterHook("/Game/CustomContent/UI/CameraWigetSlate.CameraWigetSlate_C:Tick", function(Context)
local CameraOffsetWidget = Context:get()
if not CameraOffsetWidget:IsValid() then print("CameraOffsetWidget is not valid.\n") return end
local name = CameraOffsetWidget:GetPropertyValue("Name")
name = name:ToString()
local CameraOffset = CameraOffsetWidget:GetPropertyValue("CameraOffset")
if funcHooked == false then
print("the func is hooked")
funcHooked = true
end
if bNeedsReloading == false then
if name == "CameraOffsetX" and currentCam ~= "firstperson" then
cameraOffsetsSettings[currentCam]["X"] = CameraOffset
elseif name == "CameraOffsetY" and currentCam ~= "firstperson" then
cameraOffsetsSettings[currentCam]["Y"] = CameraOffset
elseif name == "CameraOffsetZ" and currentCam ~= "firstperson" then
cameraOffsetsSettings[currentCam]["Z"] = CameraOffset
elseif name == "CameraConfig" and currentCam ~= "firstperson" then
local flooredOffset = math.floor(CameraOffset)
if cameraConfig ~= flooredOffset then
saveSettings()
cameraConfig = flooredOffset
loadCameraSettings()
end
elseif name == "CameraName" then
local flooredOffset = string.format("%s", math.floor(CameraOffset))
if currentCam ~= allCams[flooredOffset] and currentCam ~= "firstperson" then
saveSettings()
currentCam = fif(allCams[flooredOffset] == nil, currentCam, allCams[flooredOffset])
if currentCam == "firstperson" then
retrieveFpsCameras()
setCharacterInFPSView()
else
loadCameraSettings()
end
elseif currentCam == "firstperson" and currentCam ~= allCams[flooredOffset] then
Json.saveTable(currentCam, "Settings.json", "lastEditedCamera")
currentCam = allCams[flooredOffset]
revertCharacterView()
loadCameraSettings()
end
end
end
setGlblCameraStack()
end)
end
function retrieveFpsCameras()
Glbl_BP_PitchToTransformCurves_Default_C = FindAllOf("BP_PitchToTransformCurves_Default_C")
Glbl_BP_AmbientCamAnim_Idle_C = FindAllOf("BP_AmbientCamAnim_Idle_C")
Glbl_BP_AmbientCamAnim_Jog_C = FindAllOf("BP_AmbientCamAnim_Jog_C")
Glbl_CameraStackBehaviorCollisionPrediction = FindAllOf("CameraStackBehaviorCollisionPrediction")
end
@pinguluk
Copy link
Author

How to save the file

Screenshot_562

Where to place it

Screenshot_563

@Kubiuks
Copy link

Kubiuks commented May 23, 2024

I've applied it and used the newer RE-UE4SS (from nexus page) but updating presets still does not have any effect on the camera, I have all required mods as well. Any idea what might be the problem?

@pinguluk
Copy link
Author

I've applied it and used the newer RE-UE4SS (from nexus page) but updating presets still does not have any effect on the camera, I have all required mods as well. Any idea what might be the problem?

No idea, I haven't touch the game for a long time and maybe the mod has been updated. Try the latest version from the author?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment