Hello. It's not and Issue, but I manage the same camera swing work for headtracking if you want to have a look and implement in to your mod. It really makes a difference when backing up to hook something. Thank you for the amazing mods
CabView = {}
CabView.modName = g_currentModName
CabView.specName = ("spec_%s.cabView"):format(g_currentModName)
function CabView.prerequisitesPresent(specializations)
return SpecializationUtil.hasSpecialization(Enterable, specializations)
end
function CabView.registerEventListeners(vehicleType)
SpecializationUtil.registerEventListener(vehicleType, "onLoad", CabView)
SpecializationUtil.registerEventListener(vehicleType, "onEnterVehicle", CabView)
SpecializationUtil.registerEventListener(vehicleType, "onLeaveVehicle", CabView)
SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", CabView)
SpecializationUtil.registerEventListener(vehicleType, "saveToXMLFile", CabView)
end
function CabView:saveToXMLFile(xmlFile, key)
local spec = self[CabView.specName]
if spec ~= nil and spec.seatHeightOffset ~= 0 then
local correctedKey = key:gsub(CabView.modName..".", "")
setXMLFloat(xmlFile.handle, correctedKey .. "#seatHeightOffset", spec.seatHeightOffset or 0)
end
end
function CabView:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
if self.isClient then
local spec = self[CabView.specName]
self:clearActionEventsTable(spec.actionEvents)
if isActiveForInputIgnoreSelection then
local _, actionEventId
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_LEAN_FORWARD", self, CabView.KeyDown_LeanForward, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_LEAN_TOGGLE", self, CabView.KeyDown_LeanToggle, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_RAISE_SEAT", self, CabView.KeyDown_SeatRaise, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_LOWER_SEAT", self, CabView.KeyDown_SeatLower, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_RESET_VIEW", self, CabView.KeyDown_ResetView, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
end
end
end
function CabView:onLoad(savegame)
local spec = self[CabView.specName]
spec.restrictLean = (self.typeDesc == 'car' or self.typeDesc == 'truck' or self.typeName == 'carFillable')
if self.spec_enterable ~= nil then
for _, cameraBase in pairs(self.spec_enterable.cameras) do
if cameraBase.isInside then
spec.originalRotX = cameraBase.origRotX
spec.originalRotY = cameraBase.origRotY%(2*math.pi)
spec.originalRotZ = cameraBase.origRotZ
spec.rotationOffset = spec.originalRotY - math.pi
end
end
end
spec.seatHeightOffset = 0
if savegame ~= nil and savegame.xmlFile ~= nil then
spec.seatHeightOffset = getXMLFloat(savegame.xmlFile.handle, savegame.key .. ".cabView#seatHeightOffset") or 0
end
end
function CabView:onEnterVehicle(isControlling)
if isControlling then
local spec = self[CabView.specName]
spec.resetView = true
spec.lean = 0
end
end
function CabView:onLeaveVehicle()
local spec = self[CabView.specName]
spec.lean = 0
end
function CabView:KeyDown_LeanForward(_, inputValue)
local spec = self[CabView.specName]
if spec then spec.leanButtonPressed = (inputValue == 1) end
end
function CabView:KeyDown_LeanToggle(_, inputValue)
local spec = self[CabView.specName]
if spec and inputValue == 1 then spec.leanButtonPressed = not spec.leanButtonPressed end
end
function CabView:KeyDown_SeatRaise(_, inputValue)
local spec = self[CabView.specName]
if spec then spec.seatRaiseButtonPressed = (inputValue == 1) end
end
function CabView:KeyDown_SeatLower(_, inputValue)
local spec = self[CabView.specName]
if spec then spec.seatLowerButtonPressed = (inputValue == 1) end
end
function CabView:KeyDown_ResetView(_, inputValue)
local spec = self[CabView.specName]
if spec and inputValue == 1 then spec.resetView = true end
end
function CabView:vehicleCameraUpdate(superFunc, dt)
local spec = self.vehicle[CabView.specName]
if not spec then return superFunc(self, dt) end
superFunc(self, dt)
if self.isInside then
local headTrackingActive = g_gameSettings:getValue("isHeadTrackingEnabled") and isHeadTrackingAvailable() and self.allowHeadTracking
-- FIX: Limit Mouse Rotation to +/- 180 degrees (Stop the 360 spinning)
if not headTrackingActive then
local center = spec.originalRotY
self.rotY = math.clamp(self.rotY, center - math.pi, center + math.pi)
end
local angle
if headTrackingActive then
local _, hyaw, _ = getHeadTrackingRotation()
angle = hyaw or 0
else
angle = math.clamp(self.rotY-(math.pi+spec.rotationOffset), -math.pi, math.pi)
end
-- SEAT HEIGHT ADJUSTMENT
if spec.seatRaiseButtonPressed then
spec.seatHeightOffset = math.min(0.20, spec.seatHeightOffset + dt/5000)
elseif spec.seatLowerButtonPressed then
spec.seatHeightOffset = math.max(-0.20, spec.seatHeightOffset - dt/5000)
end
-- DIRECTIONAL LEAN (Mouse Only)
if spec.leanButtonPressed and not headTrackingActive then
spec.lean = math.min(0.4, spec.lean + dt/1000)
else
spec.lean = math.max(0, spec.lean - dt/1000)
end
local totalSide = 0
local totalForward = 0
local totalPitch = 0
-- Apply Manual Lean (Mouse Only - Zoom into panels)
if spec.lean > 0 then
totalSide = spec.lean * math.sin(self.rotY - spec.originalRotY)
totalForward = spec.lean * math.cos(self.rotY - spec.originalRotY)
end
-- AUTOMATIC HITCH VIEW
if math.abs(angle) > math.pi/2 then
local backRatio = (math.abs(angle) - math.pi/2) / (math.pi/2)
local autoSide = 0
local autoBack = 0
if angle > math.pi/2 then autoSide = (angle-math.pi/2)/(2*math.pi) end
if angle < -math.pi/2 then autoSide = (angle+math.pi/2)/(2*math.pi) end
if not spec.restrictLean then
-- Keep the limits we liked: 0.6 for tracker, 0.15 for mouse
local maxSlide = headTrackingActive and 0.6 or 0.15
local maxPitch = headTrackingActive and -0.45 or -0.20
autoBack = -(maxSlide * backRatio)
totalPitch = maxPitch * backRatio
end
totalSide = totalSide + autoSide*math.cos(-spec.rotationOffset) - autoBack*math.sin(-spec.rotationOffset)
totalForward = totalForward + autoSide*math.sin(-spec.rotationOffset) + autoBack*math.cos(-spec.rotationOffset)
end
-- APPLY TRANSLATION
local tx, ty, tz = getTranslation(self.cameraPositionNode)
setTranslation(self.cameraPositionNode, tx + totalSide, ty + spec.seatHeightOffset, tz + totalForward)
-- APPLY PITCH
if totalPitch ~= 0 then
local rx, ry, rz = getRotation(self.cameraNode)
setRotation(self.cameraNode, rx + totalPitch, ry, rz)
end
end
end
VehicleCamera.update = Utils.overwrittenFunction(VehicleCamera.update, CabView.vehicleCameraUpdate)
Hello. It's not and Issue, but I manage the same camera swing work for headtracking if you want to have a look and implement in to your mod. It really makes a difference when backing up to hook something. Thank you for the amazing mods
CabView = {}
CabView.modName = g_currentModName
CabView.specName = ("spec_%s.cabView"):format(g_currentModName)
function CabView.prerequisitesPresent(specializations)
return SpecializationUtil.hasSpecialization(Enterable, specializations)
end
function CabView.registerEventListeners(vehicleType)
SpecializationUtil.registerEventListener(vehicleType, "onLoad", CabView)
SpecializationUtil.registerEventListener(vehicleType, "onEnterVehicle", CabView)
SpecializationUtil.registerEventListener(vehicleType, "onLeaveVehicle", CabView)
SpecializationUtil.registerEventListener(vehicleType, "onRegisterActionEvents", CabView)
SpecializationUtil.registerEventListener(vehicleType, "saveToXMLFile", CabView)
end
function CabView:saveToXMLFile(xmlFile, key)
local spec = self[CabView.specName]
if spec ~= nil and spec.seatHeightOffset ~= 0 then
local correctedKey = key:gsub(CabView.modName..".", "")
setXMLFloat(xmlFile.handle, correctedKey .. "#seatHeightOffset", spec.seatHeightOffset or 0)
end
end
function CabView:onRegisterActionEvents(isActiveForInput, isActiveForInputIgnoreSelection)
if self.isClient then
local spec = self[CabView.specName]
self:clearActionEventsTable(spec.actionEvents)
if isActiveForInputIgnoreSelection then
local _, actionEventId
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_LEAN_FORWARD", self, CabView.KeyDown_LeanForward, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_LEAN_TOGGLE", self, CabView.KeyDown_LeanToggle, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_RAISE_SEAT", self, CabView.KeyDown_SeatRaise, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_LOWER_SEAT", self, CabView.KeyDown_SeatLower, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
_, actionEventId = self:addActionEvent(spec.actionEvents, "CABVIEW_RESET_VIEW", self, CabView.KeyDown_ResetView, true, true, false, true, true, nil )
g_inputBinding:setActionEventTextVisibility(actionEventId, false)
end
end
end
function CabView:onLoad(savegame)
local spec = self[CabView.specName]
spec.restrictLean = (self.typeDesc == 'car' or self.typeDesc == 'truck' or self.typeName == 'carFillable')
if self.spec_enterable ~= nil then
for _, cameraBase in pairs(self.spec_enterable.cameras) do
if cameraBase.isInside then
spec.originalRotX = cameraBase.origRotX
spec.originalRotY = cameraBase.origRotY%(2*math.pi)
spec.originalRotZ = cameraBase.origRotZ
spec.rotationOffset = spec.originalRotY - math.pi
end
end
end
spec.seatHeightOffset = 0
if savegame ~= nil and savegame.xmlFile ~= nil then
spec.seatHeightOffset = getXMLFloat(savegame.xmlFile.handle, savegame.key .. ".cabView#seatHeightOffset") or 0
end
end
function CabView:onEnterVehicle(isControlling)
if isControlling then
local spec = self[CabView.specName]
spec.resetView = true
spec.lean = 0
end
end
function CabView:onLeaveVehicle()
local spec = self[CabView.specName]
spec.lean = 0
end
function CabView:KeyDown_LeanForward(_, inputValue)
local spec = self[CabView.specName]
if spec then spec.leanButtonPressed = (inputValue == 1) end
end
function CabView:KeyDown_LeanToggle(_, inputValue)
local spec = self[CabView.specName]
if spec and inputValue == 1 then spec.leanButtonPressed = not spec.leanButtonPressed end
end
function CabView:KeyDown_SeatRaise(_, inputValue)
local spec = self[CabView.specName]
if spec then spec.seatRaiseButtonPressed = (inputValue == 1) end
end
function CabView:KeyDown_SeatLower(_, inputValue)
local spec = self[CabView.specName]
if spec then spec.seatLowerButtonPressed = (inputValue == 1) end
end
function CabView:KeyDown_ResetView(_, inputValue)
local spec = self[CabView.specName]
if spec and inputValue == 1 then spec.resetView = true end
end
function CabView:vehicleCameraUpdate(superFunc, dt)
local spec = self.vehicle[CabView.specName]
if not spec then return superFunc(self, dt) end
end
VehicleCamera.update = Utils.overwrittenFunction(VehicleCamera.update, CabView.vehicleCameraUpdate)