Also, I want to point out that I have the code… It just doesn’t work.
That’s what I got. Probably the logic is ugly:
(And here too much bugs)
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")
local screenGui = script.Parent
local viewports = {
Red = screenGui.Red,
Green = screenGui.Green,
Blue = screenGui.Blue
}
local CONFIG = {
CAMERA_OFFSET = {
Red = Vector3.new(0.3, 0.2, 0.2),
Green = Vector3.new(0.15, 0.1, 0.1),
Blue = Vector3.new(-0.3, -0.2, -0.2)
},
MOTION_MULTIPLIER = {
Red = 3,
Green = 2,
Blue = 1
},
BASE_INTENSITY = 1,
MOTION_SENSITIVITY = 0.3,
RANDOM_INTENSITY = 0.02
}
local clones = {}
local previousCameraPos = Vector3.new()
local currentIntensity = CONFIG.BASE_INTENSITY
for name, viewport in (viewports) do
local worldModel = viewport:FindFirstChildOfClass("WorldModel") or Instance.new("WorldModel")
worldModel.Name = "WorldModel"
worldModel.Parent = viewport
local camera = Instance.new("Camera")
camera.FieldOfView = 70
camera.CameraType = Enum.CameraType.Scriptable
viewport.CurrentCamera = camera
clones[viewport] = {}
end
local function updateIntensity(delta)
local velocity = (workspace.CurrentCamera.CFrame.Position - previousCameraPos).Magnitude
local targetIntensity = CONFIG.BASE_INTENSITY + (velocity * CONFIG.MOTION_SENSITIVITY)
currentIntensity = currentIntensity + (targetIntensity - currentIntensity) * delta * 5
end
local function updateClones()
for _, obj in ipairs(workspace:GetChildren()) do
if not obj:IsA("Terrain") and not obj:IsA("Camera") then
for name, viewport in pairs(viewports) do
local viewportClones = clones[viewport]
if not viewportClones[obj] then
obj.Archivable = true
local clone = obj:Clone()
clone.Parent = viewport.WorldModel
viewportClones[obj] = clone
end
local clone = viewportClones[obj]
if obj:IsA("BasePart") then
clone.CFrame = obj.CFrame
elseif obj:IsA("Model") and obj.PrimaryPart then
if obj ~= game.Players.LocalPlayer.Character then
clone:SetPrimaryPartCFrame(obj.PrimaryPart.CFrame)
end
end
end
end
end
for _, viewport in pairs(viewports) do
for original, clone in pairs(clones[viewport]) do
if not original:IsDescendantOf(workspace) then
clone:Destroy()
clones[viewport][original] = nil
end
end
end
end
local function updateCameras(delta)
local baseCFrame = workspace.CurrentCamera.CFrame
local basePos = baseCFrame.Position
updateIntensity(delta)
local randomOffset = Vector3.new(
math.random() * CONFIG.RANDOM_INTENSITY,
math.random() * CONFIG.RANDOM_INTENSITY,
math.random() * CONFIG.RANDOM_INTENSITY
)
for name, viewport in pairs(viewports) do
local offset = CONFIG.CAMERA_OFFSET[name] * currentIntensity
local motionOffset = (basePos - previousCameraPos) * CONFIG.MOTION_MULTIPLIER[name]
viewport.CurrentCamera.CFrame = baseCFrame * CFrame.new(offset + motionOffset + randomOffset)
end
previousCameraPos = basePos
end
RunService.RenderStepped:Connect(function(delta)
updateClones()
updateCameras(delta)
end)
Updated
local RunService = game:GetService("RunService")
local screenGui = script.Parent
local viewports = {
Red = screenGui.Red,
Green = screenGui.Green,
Blue = screenGui.Blue
}
local CONFIG = {
CAMERA_OFFSET = {
Red = Vector3.new(0.12, 0.4, 0.2),
Green = Vector3.new(0.2, 0.2, 0.1),
Blue = Vector3.new(-0.145, -0.3, 0.15)
},
MOTION_MULTIPLIER = {
Red = 1.0,
Green = 0.8,
Blue = 0.6
},
BASE_INTENSITY = 0.1,
MOTION_SENSITIVITY = 0.15,
RANDOM_INTENSITY = 0.005,
SMOOTHING = 0.9,
DISTANCE_FADE = 1,
MAX_DISTANCE_MULTIPLIER = 2.0,
COLOR_TRAIL_LENGTH = 75
}
local clones = {}
local previousCameraPos = Vector3.new()
local currentIntensity = CONFIG.BASE_INTENSITY
local cameraPosHistory = { }
local function updateCameraPositionsHistory(newPosition)
table.insert(cameraPosHistory, newPosition)
while #cameraPosHistory > CONFIG.COLOR_TRAIL_LENGTH do
table.remove(cameraPosHistory, 1)
end
end
local function getAveragePositionInHistory()
local sum = Vector3.new(0, 0, 0)
for _, pos in ipairs(cameraPosHistory) do
sum = sum + pos
end
return sum / #cameraPosHistory
end
for name, viewport in pairs(viewports) do
local worldModel = viewport:FindFirstChildOfClass("WorldModel") or Instance.new("WorldModel")
worldModel.Name = "WorldModel"
worldModel.Parent = viewport
local camera = Instance.new("Camera")
camera.FieldOfView = 70
camera.CameraType = Enum.CameraType.Scriptable
viewport.CurrentCamera = camera
clones[viewport] = {}
end
local function updateIntensity(delta)
local velocity = (workspace.CurrentCamera.CFrame.Position - previousCameraPos).Magnitude
local targetIntensity = CONFIG.BASE_INTENSITY + (velocity * CONFIG.MOTION_SENSITIVITY)
currentIntensity = currentIntensity + (targetIntensity - currentIntensity) * delta * 5
end
local function updateClones()
for _, obj in ipairs(workspace:GetChildren()) do
if not obj:IsA("Terrain") and not obj:IsA("Camera") then
for name, viewport in pairs(viewports) do
local viewportClones = clones[viewport]
if not viewportClones[obj] then
obj.Archivable = true
local clone = obj:Clone()
clone.Parent = viewport.WorldModel
viewportClones[obj] = clone
end
local clone = viewportClones[obj]
if obj:IsA("BasePart") then
clone.CFrame = obj.CFrame
elseif obj:IsA("Model") and obj.PrimaryPart then
if obj ~= game.Players.LocalPlayer.Character then
clone:SetPrimaryPartCFrame(obj.PrimaryPart.CFrame)
end
end
end
end
end
for _, viewport in pairs(viewports) do
for original, clone in pairs(clones[viewport]) do
if not original:IsDescendantOf(workspace) then
clone:Destroy()
clones[viewport][original] = nil
end
end
end
end
local function getLookDirection()
return workspace.CurrentCamera.CFrame.LookVector
end
local function getDistanceMultiplier(position)
local camera = workspace.CurrentCamera
local distance = (position - camera.CFrame.Position).Magnitude
local fade = math.clamp((distance - CONFIG.DISTANCE_FADE) / CONFIG.DISTANCE_FADE, 0, 1)
return 1 + (fade * (CONFIG.MAX_DISTANCE_MULTIPLIER - 1))
end
local smoothedIntensity = CONFIG.BASE_INTENSITY
local smoothedOffset = Vector3.new()
local function updateCameras(delta)
local baseCFrame = workspace.CurrentCamera.CFrame or CFrame.new()
local basePos = baseCFrame.Position
updateCameraPositionsHistory(basePos)
local lookDir = getLookDirection()
local velocity = (basePos - previousCameraPos).Magnitude
local targetIntensity = CONFIG.BASE_INTENSITY + (velocity * CONFIG.MOTION_SENSITIVITY)
smoothedIntensity = smoothedIntensity + (targetIntensity - smoothedIntensity) * (1 - CONFIG.SMOOTHING)
local randomOffset = Vector3.new(
math.random() * CONFIG.RANDOM_INTENSITY,
math.random() * CONFIG.RANDOM_INTENSITY,
math.random() * CONFIG.RANDOM_INTENSITY
)
smoothedOffset = smoothedOffset:Lerp(randomOffset, 1 - CONFIG.SMOOTHING)
local averagePosition = getAveragePositionInHistory()
for name, viewport in pairs(viewports) do
local baseOffset = CONFIG.CAMERA_OFFSET[name]
local motionOffset = (averagePosition - previousCameraPos) * CONFIG.MOTION_MULTIPLIER[name]
local rightVector = baseCFrame.RightVector
local upVector = baseCFrame.UpVector
local forwardVector = baseCFrame.LookVector
local adjustedOffset = (rightVector * baseOffset.X + upVector * baseOffset.Y + forwardVector * baseOffset.Z) * smoothedIntensity
local distanceMultiplier = getDistanceMultiplier(basePos)
adjustedOffset = adjustedOffset * distanceMultiplier
viewport.CurrentCamera.CFrame = baseCFrame * CFrame.new(
adjustedOffset +
(motionOffset * smoothedIntensity) +
(smoothedOffset * distanceMultiplier)
)
end
previousCameraPos = basePos
end
RunService.RenderStepped:Connect(function(delta)
updateClones()
updateCameras(delta)
end)