405 lines
9.9 KiB
Lua
405 lines
9.9 KiB
Lua
local CoreGui = game:GetService("CoreGui")
|
|
local GuiRoot = CoreGui:FindFirstChild("RobloxGui")
|
|
local Modules = GuiRoot:FindFirstChild("Modules")
|
|
local ShellModules = Modules:FindFirstChild("Shell")
|
|
local Utility = require(ShellModules:FindFirstChild('Utility'))
|
|
local RunService = game:GetService("RunService")
|
|
local UserInputService = game:GetService('UserInputService')
|
|
local Lighting = game:GetService('Lighting')
|
|
|
|
local BackgroundTintColor = Color3.new(0.0784, 0.1686, 0.2353)
|
|
|
|
local ColorCorrection = Utility.Create'ColorCorrectionEffect'
|
|
{
|
|
Brightness = 0.3;
|
|
Contrast = 0.5;
|
|
Saturation = -1;
|
|
TintColor = BackgroundTintColor;
|
|
Enabled = true;
|
|
Parent = Lighting;
|
|
}
|
|
|
|
local Blur = Utility.Create'BlurEffect'
|
|
{
|
|
Size = 10;
|
|
Enabled = true;
|
|
Parent = Lighting;
|
|
}
|
|
|
|
local Bloom = Utility.Create'BloomEffect'
|
|
{
|
|
Intensity = 0.05;
|
|
Size = 24;
|
|
Threshold = 0.95;
|
|
Enabled = true;
|
|
Parent = Lighting;
|
|
}
|
|
|
|
local function GetCameraParts(model)
|
|
local parts = {}
|
|
for i, part in pairs(model:GetChildren()) do
|
|
parts[tonumber(part.Name:sub(4, -1))] = part
|
|
part.Transparency = 1
|
|
end
|
|
return parts
|
|
end
|
|
|
|
local myCameraSets = nil
|
|
|
|
local function GetCameraSets()
|
|
if myCameraSets == nil then
|
|
myCameraSets = {}
|
|
for k, f in pairs(workspace:WaitForChild("Cameras"):GetChildren()) do
|
|
myCameraSets[f.Name] = GetCameraParts(f)
|
|
end
|
|
end
|
|
return myCameraSets
|
|
end
|
|
|
|
|
|
local function onCameraChanged()
|
|
if workspace.CurrentCamera then
|
|
workspace.CurrentCamera.CameraType = 'Scriptable'
|
|
end
|
|
end
|
|
|
|
workspace:GetPropertyChangedSignal('CurrentCamera'):connect(function()
|
|
onCameraChanged()
|
|
end)
|
|
onCameraChanged()
|
|
|
|
|
|
local cameraMoveCn = nil
|
|
|
|
local gamepadInput = Vector2.new(0, 0)
|
|
|
|
|
|
|
|
local CameraManager = {}
|
|
|
|
function CameraManager:EnableCameraControl()
|
|
cameraMoveCn = Utility.DisconnectEvent(cameraMoveCn)
|
|
cameraMoveCn = UserInputService.InputChanged:connect(function(input)
|
|
if input.KeyCode == Enum.KeyCode.Thumbstick2 then
|
|
gamepadInput = input.Position or gamepadInput
|
|
gamepadInput = Vector2.new(gamepadInput.X, gamepadInput.Y)
|
|
end
|
|
end)
|
|
end
|
|
|
|
function CameraManager:DisableCameraControl()
|
|
cameraMoveCn = Utility.DisconnectEvent(cameraMoveCn)
|
|
gamepadInput = Vector2.new(0, 0)
|
|
end
|
|
|
|
|
|
local getGamepadInputCFrame;
|
|
do
|
|
local gamepadInputLerping = Vector2.new(0, 0)
|
|
local timestamp0 = tick()
|
|
function getGamepadInputCFrame()
|
|
local timestamp1 = tick()
|
|
local deltaTime = timestamp1 - timestamp0
|
|
timestamp0 = timestamp1
|
|
local unit = 0.125 ^ deltaTime
|
|
gamepadInputLerping = gamepadInputLerping * unit + gamepadInput * (1 - unit)
|
|
return CFrame.new(
|
|
gamepadInputLerping.X/8, gamepadInputLerping.Y/8, 0) * CFrame.Angles(0, -gamepadInputLerping.X / 12, 0) * CFrame.Angles(gamepadInputLerping.Y / 12, 0, 0)
|
|
end
|
|
end
|
|
|
|
|
|
local defaultCFrame = CFrame.new();
|
|
|
|
local function defaultGetFrameInfo()
|
|
return {
|
|
CFrame = defaultCFrame;
|
|
Contrast = 0.5;
|
|
Saturation = -1;
|
|
TintColor = BackgroundTintColor;
|
|
BlurSize = 10;
|
|
}
|
|
end
|
|
|
|
local getFrameInfo = defaultGetFrameInfo
|
|
|
|
|
|
local function startEternalRenderStep()
|
|
RunService:BindToRenderStep("CameraScriptCutsceneLerp", Enum.RenderPriority.Camera.Value,
|
|
function()
|
|
local info = getFrameInfo()
|
|
workspace.CurrentCamera.CoordinateFrame = info.CFrame
|
|
ColorCorrection.Contrast = info.Contrast
|
|
ColorCorrection.Saturation = info.Saturation
|
|
ColorCorrection.TintColor = info.TintColor
|
|
Blur.Size = info.BlurSize
|
|
end
|
|
)
|
|
end
|
|
|
|
|
|
local function transitionToCameraAnimator(cameraAnimator, transitionDuration, targetBrightness, targetBlurEnabled, targetBloomEnabled)
|
|
Utility.PropertyTweener(ColorCorrection, "Brightness", ColorCorrection.Brightness,
|
|
-1, transitionDuration, Utility.EaseInOutQuad, true,
|
|
function()
|
|
getFrameInfo = cameraAnimator:get_getFrameInfo()
|
|
Blur.Enabled = targetBlurEnabled
|
|
Bloom.Enabled = targetBloomEnabled
|
|
Utility.PropertyTweener(ColorCorrection, "Brightness", ColorCorrection.Brightness,
|
|
targetBrightness, transitionDuration, Utility.EaseInOutQuad, true)
|
|
end)
|
|
end
|
|
|
|
|
|
local function CFrameBezierLerp(cframes, t)
|
|
local cframes2 = {}
|
|
for i = 1, #cframes - 1 do
|
|
cframes2[i] = cframes[i]:lerp(cframes[i + 1], t)
|
|
end
|
|
if #cframes2 == 1 then
|
|
return cframes2[1]
|
|
end
|
|
return CFrameBezierLerp(cframes2, t)
|
|
end
|
|
|
|
|
|
local function getCFrameList(cameras)
|
|
local cframes = {}
|
|
for i = 1, #cameras do
|
|
cframes[i] = cameras[i].CFrame
|
|
end
|
|
return cframes
|
|
end
|
|
|
|
|
|
local function CameraSeriesAnimator(cameraSeries, length)
|
|
local timestamp0 = 0
|
|
local cameraIndex = 0
|
|
local cframes = nil
|
|
local isRunning = false
|
|
local tweenTable = {}
|
|
|
|
local animationInfo = {
|
|
Contrast = -1;
|
|
BlurSize = 50;
|
|
}
|
|
|
|
local function myGetFrameInfo()
|
|
local t = Utility.Clamp(0, 1, (tick() - timestamp0) / length)
|
|
|
|
return {
|
|
CFrame = CFrameBezierLerp(cframes, t) * getGamepadInputCFrame();
|
|
Contrast = animationInfo.Contrast;
|
|
Saturation = -1;
|
|
TintColor = BackgroundTintColor;
|
|
BlurSize = animationInfo.BlurSize;
|
|
}
|
|
end
|
|
|
|
local function advance()
|
|
if not isRunning then
|
|
return
|
|
end
|
|
cameraIndex = cameraIndex + 1
|
|
if cameraIndex > #cameraSeries then
|
|
cameraIndex = 1
|
|
end
|
|
cameraSeries[cameraIndex].init()
|
|
cframes = getCFrameList(cameraSeries[cameraIndex].cameras)
|
|
timestamp0 = tick()
|
|
end
|
|
|
|
runCameraSeries = function(transitionDuration)
|
|
local timePassed = tick() - timestamp0
|
|
for i = #tweenTable, 1, -1 do
|
|
if tweenTable[i]:IsFinished() then
|
|
table.remove(tweenTable, i)
|
|
end
|
|
end
|
|
|
|
if timePassed >= length then
|
|
local newTween = Utility.PropertyTweener(animationInfo, "Contrast", animationInfo.Contrast, 0.5, transitionDuration, Utility.EaseInOutQuad, true)
|
|
table.insert(tweenTable, newTween)
|
|
newTween = Utility.PropertyTweener(animationInfo, "BlurSize", animationInfo.BlurSize, 10, transitionDuration, Utility.EaseInOutQuad, true)
|
|
table.insert(tweenTable, newTween)
|
|
advance()
|
|
elseif timePassed >= length - transitionDuration and #tweenTable == 0 then
|
|
local newTween = Utility.PropertyTweener(animationInfo, "Contrast", animationInfo.Contrast, -1, transitionDuration, Utility.EaseInOutQuad, true)
|
|
table.insert(tweenTable, newTween)
|
|
newTween = Utility.PropertyTweener(animationInfo, "BlurSize", animationInfo.BlurSize, 50, transitionDuration, Utility.EaseInOutQuad, true)
|
|
table.insert(tweenTable, newTween)
|
|
end
|
|
end
|
|
|
|
local function startCameraSeries()
|
|
local tween = Utility.PropertyTweener(animationInfo, "Contrast", animationInfo.Contrast, 0.5, 4, Utility.EaseInOutQuad, true)
|
|
table.insert(tweenTable, tween)
|
|
tween = Utility.PropertyTweener(animationInfo, "BlurSize", animationInfo.BlurSize, 10, 4, Utility.EaseInOutQuad, true)
|
|
table.insert(tweenTable, tween)
|
|
advance()
|
|
end
|
|
|
|
local this = {}
|
|
|
|
function this:Start()
|
|
isRunning = true
|
|
startCameraSeries()
|
|
RunService:BindToRenderStep("runCameraSeries", Enum.RenderPriority.Camera.Value + 1, function()
|
|
runCameraSeries(1.7)
|
|
end)
|
|
end
|
|
|
|
function this:Stop()
|
|
isRunning = false
|
|
for i = #tweenTable, 1, -1 do
|
|
local tween = table.remove(tweenTable, i)
|
|
tween:Finish()
|
|
end
|
|
animationInfo = {
|
|
Contrast = 0.5;
|
|
BlurSize = 10;
|
|
}
|
|
RunService:UnbindFromRenderStep("runCameraSeries")
|
|
end
|
|
|
|
function this:get_getFrameInfo()
|
|
return myGetFrameInfo
|
|
end
|
|
|
|
return this
|
|
end
|
|
|
|
|
|
local function CameraZoomAnimator(cframes, length, pathFunc)
|
|
local timestamp0 = 0
|
|
|
|
local this = {}
|
|
|
|
function this:Reset()
|
|
timestamp0 = tick()
|
|
end
|
|
|
|
function this:Update(inCframes, length)
|
|
cframes = inCframes
|
|
timestamp0 = tick()
|
|
end
|
|
|
|
local function myGetFrameInfo()
|
|
local t = Utility.Clamp(0, 1, (tick() - timestamp0) / length)
|
|
|
|
return {
|
|
CFrame = CFrameBezierLerp(cframes, pathFunc(t));
|
|
Contrast = 0.35;
|
|
Saturation = 0.175;
|
|
TintColor = Color3.fromRGB(255, 255, 255);
|
|
BlurSize = 1;
|
|
}
|
|
end
|
|
|
|
function this:get_getFrameInfo()
|
|
return myGetFrameInfo
|
|
end
|
|
|
|
return this
|
|
end
|
|
|
|
|
|
pcall(function()
|
|
local function recurse(model)
|
|
local children = model:GetChildren()
|
|
for i = 1, #children do
|
|
local child = children[i]
|
|
if child:IsA("BasePart") then
|
|
child.Locked = true
|
|
child.Anchored = true
|
|
child.CanCollide = false
|
|
end
|
|
recurse(child)
|
|
end
|
|
end
|
|
recurse(workspace)
|
|
end)
|
|
|
|
|
|
local ZoneManager = require(script.Parent:WaitForChild("CameraManagerModules"):WaitForChild("ZoneManager"))
|
|
|
|
local avatarEditorCameraAnimator = nil
|
|
local flythroughAnimator = nil
|
|
|
|
local avatarEditorZoomCFrames = {
|
|
CFrame.new(
|
|
10.2426682, 5.1197648, -30.9536419,
|
|
-0.946675897, 0.123298854, -0.297661126,
|
|
0.0000000, 0.92387563, 0.382692933,
|
|
0.322187454, 0.36228618, -0.874610782),
|
|
|
|
CFrame.new(
|
|
12.50625, 4.83650, -24.764325,
|
|
-0.94241035, 0.0557777137, -0.329775006,
|
|
0.0000000, 0.98599577, 0.166770056,
|
|
0.334458828, 0.157165825, -0.92921263)
|
|
}
|
|
|
|
function CameraManager:CameraMoveToAsync()
|
|
local cameraSets = GetCameraSets()
|
|
|
|
startEternalRenderStep();
|
|
|
|
flythroughAnimator = CameraSeriesAnimator({
|
|
{
|
|
init = function() ZoneManager:SetZone("City") end;
|
|
cameras = cameraSets["City"]
|
|
},
|
|
{
|
|
init = function() ZoneManager:SetZone("Space") end;
|
|
cameras = cameraSets["Space"]
|
|
},
|
|
{
|
|
init = function() ZoneManager:SetZone("Volcano") end;
|
|
cameras = cameraSets["Volcano"]
|
|
},
|
|
}, 60)
|
|
|
|
avatarEditorCameraAnimator = CameraZoomAnimator(avatarEditorZoomCFrames, 1.0, function(t)
|
|
t = Utility.Clamp(0, 1, t)
|
|
return t * (2 - t)
|
|
end)
|
|
|
|
flythroughAnimator:Start()
|
|
transitionToCameraAnimator(flythroughAnimator, 0.25, 0.3, true, false)
|
|
end
|
|
|
|
|
|
function CameraManager:SwitchToFlyThrough()
|
|
transitionToCameraAnimator(flythroughAnimator, 0.25, 0.3, true, false)
|
|
flythroughAnimator:Start()
|
|
end
|
|
|
|
|
|
function CameraManager:SwitchToAvatarEditor()
|
|
flythroughAnimator:Stop()
|
|
ZoneManager:SetZone("AvatarEditor")
|
|
avatarEditorCameraAnimator:Reset()
|
|
|
|
transitionToCameraAnimator(avatarEditorCameraAnimator, 0.25, 0.02, false, true)
|
|
end
|
|
|
|
local targetCFrame = avatarEditorZoomCFrames[2]
|
|
|
|
function CameraManager:UpdateAvatarEditorCamera(newCFrame)
|
|
targetCFrame = newCFrame
|
|
local frameInfo = avatarEditorCameraAnimator:get_getFrameInfo()()
|
|
|
|
avatarEditorCameraAnimator:Update(
|
|
{
|
|
frameInfo.CFrame,
|
|
targetCFrame
|
|
},
|
|
0.5
|
|
)
|
|
end
|
|
|
|
|
|
return CameraManager
|
|
|