- Joined
- Jan 30, 2013
- Messages
- 12,422
Wowie, idea sparks just by looking at this :O
if Debug then Debug.beginFile "FixedCameraLock" end
do
--[[
=============================================================================================================================================================
Fixed Camera Lock
by Antares
Locks the camera to a unit while dynamically adjusting the z-offset to disable awfulness.
Requires:
TotalInitialization https://www.hiveworkshop.com/threads/total-initialization.317099/
PrecomputedHeightMap (optional) https://www.hiveworkshop.com/threads/precomputed-synchronized-height-map.353477/
=============================================================================================================================================================
A P I
=============================================================================================================================================================
FCL_Lock(whichUnit, whichPlayer) Locks the camera of the specified player to the specified unit or the camera of the owning player of that unit,
if player is not specified.
FCL_Release(whichPlayer) Releases the camera of the specified player or for all players if no player is specified.
=============================================================================================================================================================
C O N F I G
=============================================================================================================================================================
]]
local ADJUSTMENT_INTERVAL = 0.1 ---@constant number
--The adjustment strength when the camera target is below the unit. This type of camera shift is always awful and I recommend a value of 1.
local ADJUSTMENT_STRENGTH_UP = 1.0 ---@constant number
--The adjustment strength when the camera target is above the unit. This camera shift is sometimes actually useful, so you can disable it if you want to.
local ADJUSTMENT_STRENGTH_DOWN = 1.0 ---@constant number
--===========================================================================================================================================================
local MASTER_TIMER ---@type timer
local anchor ---@type unit
local lockEnabled = false ---@type boolean
local moveableLoc ---@type location
local GetLocZ ---@type function
---@param whichUnit unit
---@param whichPlayer? player
function FCL_Lock(whichUnit, whichPlayer)
if GetLocalPlayer() == (whichPlayer or GetOwningPlayer(whichUnit)) then
SetCameraTargetController(whichUnit, 0, 0, false)
lockEnabled = true
anchor = whichUnit
end
end
---@param whichPlayer? player
function FCL_Release(whichPlayer)
if whichPlayer == nil or GetLocalPlayer() == whichPlayer then
ResetToGameCamera(0)
lockEnabled = false
end
end
local function AdjustCameraHeight()
if lockEnabled then
local dz = GetLocZ(GetUnitX(anchor), GetUnitY(anchor)) - (GetCameraTargetPositionZ() - GetCameraField(CAMERA_FIELD_ZOFFSET))
if dz > 0 then
SetCameraField(CAMERA_FIELD_ZOFFSET, ADJUSTMENT_STRENGTH_UP*dz, ADJUSTMENT_INTERVAL)
else
SetCameraField(CAMERA_FIELD_ZOFFSET, ADJUSTMENT_STRENGTH_DOWN*dz, ADJUSTMENT_INTERVAL)
end
end
end
OnInit.final("FixedCameraLock", function()
local precomputedHeightMap = Require.optionally "PrecomputedHeightMap"
if precomputedHeightMap then
GetLocZ = _G.GetLocZ
else
moveableLoc = Location(0, 0)
GetLocZ = function(x, y)
MoveLocation(moveableLoc, x, y)
return GetLocationZ(moveableLoc)
end
end
MASTER_TIMER = CreateTimer()
TimerStart(MASTER_TIMER, ADJUSTMENT_INTERVAL, true, AdjustCameraHeight)
end)
end
if Debug then Debug.endFile() end
library FixedCameraLock initializer Init
/*
=============================================================================================================================================================
Fixed Camera Lock
by Antares
Locks the camera to a unit while dynamically adjusting the z-offset to disable awfulness.
=============================================================================================================================================================
A P I
=============================================================================================================================================================
FCL_Lock(whichUnit, whichPlayer) Locks the camera of the specified player to the specified unit.
FCL_Release(whichPlayer) Releases the camera of the specified player.
=============================================================================================================================================================
C O N F I G
=============================================================================================================================================================
*/
globals
private real ADJUSTMENT_INTERVAL = 0.1
private real ADJUSTMENT_STRENGTH_UP = 1.0
//The adjustment strength when the camera target is below the unit. This type of camera shift is always awful and I recommend a value of 1.
private real ADJUSTMENT_STRENGTH_DOWN = 1.0
//The adjustment strength when the camera target is above the unit. This type of camera shift is actually useful, so you can disable it if you want to.
//=======================================================================================================================================================
private timer MASTER_TIMER = CreateTimer()
private unit anchor
private boolean lockEnabled = false
private location moveableLoc = Location(0, 0)
endglobals
private function GetLocZ takes real x, real y returns real
call MoveLocation(moveableLoc, x, y)
return GetLocationZ(moveableLoc)
endfunction
function FCL_Lock takes unit whichUnit, player whichPlayer returns nothing
if GetLocalPlayer() == whichPlayer then
call SetCameraTargetController(whichUnit, 0, 0, false)
set lockEnabled = true
set anchor = whichUnit
endif
endfunction
function FCL_Release takes player whichPlayer returns nothing
if GetLocalPlayer() == whichPlayer then
call ResetToGameCamera(0)
set lockEnabled = false
endif
endfunction
private function AdjustCameraHeight takes nothing returns nothing
local real dz
if lockEnabled then
set dz = GetLocZ(GetUnitX(anchor), GetUnitY(anchor)) - (GetCameraTargetPositionZ() - GetCameraField(CAMERA_FIELD_ZOFFSET))
if dz > 0 then
call SetCameraField(CAMERA_FIELD_ZOFFSET, ADJUSTMENT_STRENGTH_UP*dz, ADJUSTMENT_INTERVAL)
else
call SetCameraField(CAMERA_FIELD_ZOFFSET, ADJUSTMENT_STRENGTH_DOWN*dz, ADJUSTMENT_INTERVAL)
endif
endif
endfunction
private function Init takes nothing returns nothing
call TimerStart(MASTER_TIMER, ADJUSTMENT_INTERVAL, true, function AdjustCameraHeight)
endfunction
endlibrary