Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- local runService = game:GetService("RunService")
- local players = game:GetService("Players")
- local userInput = game:GetService("UserInputService")
- local storage = game:GetService("ReplicatedStorage")
- local tweenService = game:GetService("TweenService")
- local utilities = storage:WaitForChild("Utilities")
- local intercom = require(utilities:WaitForChild("Intercom"))
- local springs = require(utilities:WaitForChild("Springs"))
- local constructionsBin = workspace:WaitForChild("Constructions")
- ----
- local lastTransparencyCollisions = {}
- local activeTweens = {}
- local cameraShakes = {}
- ----
- local RNG = Random.new()
- local HUMANOID_BASE_OFFSET = Vector3.new(0, 1.5, 0)
- local HUMANOID_POST_OFFSET = Vector3.new()
- local TOOL_BASE_OFFSET = Vector3.new(0, 2.5, 0)
- local TOOL_POST_OFFSET = Vector3.new(0, 0, 2)
- local CAMERA_POSITION = Vector3.new()
- local CAMERA_SHAKE = springs.new(Vector3.new(), 30, 0.7)
- local CAMERA_ZOOM = springs.new(10, 30, 1)
- local CAMERA_PRE_OFFSET = springs.new(Vector3.new(), 30, 1)
- local CAMERA_POST_OFFSET = springs.new(Vector3.new(), 30, 1)
- local ZOOM_INCREMENT = 1
- local ZOOM_MIN = 3
- local ZOOM_MAX = 12
- local COLLISION_TRANSPARENCY = 0.6
- local COLLISION_TWEEN_INFO_IN = TweenInfo.new(0.05, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
- local COLLISION_TWEEN_INFO_OUT = TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
- local CAMERA_ANGLES = {
- Pitch = 0,
- Yaw = 0,
- Roll = 0,
- }
- local ANGLE_CLAMPS = {
- Pitch = {math.rad(-80), math.rad(75)},
- Yaw = {-math.huge, math.huge},
- Roll = {-math.huge, math.huge}
- }
- local CAST_SCREEN_SCALES = {
- Vector2.new(0.5, 0.5),
- Vector2.new(0, 0),
- Vector2.new(1, 0),
- Vector2.new(1, 1),
- Vector2.new(0, 1),
- }
- ----
- local function clamp(val, min, max)
- if val < min then
- return min
- elseif val > max then
- return max
- else
- return val
- end
- end
- local function yawPitchRoll(x, y, z)
- return CFrame.Angles(0, y, 0) * CFrame.Angles(x, 0, z)
- end
- local function rollPitchYaw(x, y, z)
- return CFrame.Angles(0, 0, z) * CFrame.Angles(x, y, 0)
- end
- local function clampCamera()
- for index, value in next, CAMERA_ANGLES do
- CAMERA_ANGLES[index] = clamp(value, unpack(ANGLE_CLAMPS[index]))
- end
- end
- local function rotateCamera(input)
- local change = input.Delta * math.rad(1) * 0.2
- CAMERA_ANGLES.Pitch = CAMERA_ANGLES.Pitch - change.Y
- CAMERA_ANGLES.Yaw = CAMERA_ANGLES.Yaw - change.X
- clampCamera()
- end
- local function zoomCamera(input)
- local direction = math.sign(-input.Position.Z)
- local current = CAMERA_ZOOM.Target
- local rawNew = current + (direction * ZOOM_INCREMENT)
- local clamped = math.clamp(rawNew, ZOOM_MIN, ZOOM_MAX)
- CAMERA_ZOOM.Target = clamped
- end
- local function getShake()
- for index = #cameraShakes, 1, -1 do
- local data = cameraShakes[index]
- local delta = tick() - data.Start
- if delta > data.Length then
- table.remove(cameraShakes, index)
- end
- end
- return cameraShakes[1]
- end
- local function setCamera()
- local camera = workspace.CurrentCamera
- local subject = camera.CameraSubject
- if camera.CameraType ~= Enum.CameraType.Custom then
- return
- end
- if subject and subject:IsA("Model") then
- CAMERA_POST_OFFSET.Target = Vector3.new()
- CAMERA_POSITION = subject:GetModelCFrame().p
- elseif subject and subject:IsA("Humanoid") then
- if subject.Parent:FindFirstChild("Tool") then
- CAMERA_PRE_OFFSET.Target = TOOL_BASE_OFFSET
- CAMERA_POST_OFFSET.Target = TOOL_POST_OFFSET
- else
- CAMERA_PRE_OFFSET.Target = HUMANOID_BASE_OFFSET
- CAMERA_POST_OFFSET.Target = HUMANOID_POST_OFFSET
- end
- CAMERA_POSITION = subject.Torso.CFrame * CAMERA_PRE_OFFSET:Solve()
- end
- local rotatedOffset = CAMERA_POST_OFFSET:Solve() + Vector3.new(0, 0, CAMERA_ZOOM:Solve())
- local rotation = yawPitchRoll(CAMERA_ANGLES.Pitch, CAMERA_ANGLES.Yaw, CAMERA_ANGLES.Roll)
- local position = CAMERA_POSITION + (rotation * rotatedOffset)
- local shakeRotation = CFrame.new()
- local workingShake = getShake()
- if workingShake then
- local pitch = RNG:NextNumber(-0.5, 0.5) * workingShake.Intensity
- local roll = RNG:NextNumber(-0.5, 0.5) * workingShake.Intensity
- CAMERA_SHAKE.Target = Vector3.new(pitch, 0, roll)
- local set = CAMERA_SHAKE:Solve() * math.rad(1)
- local asCF = rollPitchYaw(set.X, set.Y, set.Z)
- shakeRotation = asCF
- end
- camera.CFrame = (rotation * shakeRotation) + position
- camera.Focus = CFrame.new(CAMERA_POSITION)
- userInput.MouseBehavior = Enum.MouseBehavior.LockCenter
- end
- local function findStructureFromPart(object)
- if object:IsDescendantOf(constructionsBin) then
- if object.Parent == constructionsBin then
- return object
- else
- return findStructureFromPart(object.Parent)
- end
- else
- return nil
- end
- end
- local function collideCamera()
- local ignore = {
- workspace:WaitForChild("Characters"),
- workspace:WaitForChild("Gem Bin"),
- workspace:WaitForChild("ToolEffects")
- }
- local newCollisionList = {}
- ----
- local camera = workspace.CurrentCamera
- local cframe = camera.CFrame
- local focus = camera.Focus
- local viewSize = camera.ViewportSize
- local clippingDist = 0.5
- local clippingOffset = cframe.lookVector * clippingDist
- local baseDistance = (cframe.p - focus.p).magnitude
- local shiftDistance = 0
- ----
- for _, screenVec in next, CAST_SCREEN_SCALES do
- local screenPos = viewSize * screenVec
- local castTo = camera:ViewportPointToRay(screenPos.X, screenPos.Y, clippingDist).Origin
- local castFrom = focus.p + (castTo - (cframe.p + clippingOffset))
- local ray = Ray.new(castFrom, castTo - castFrom)
- local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
- repeat
- local goodHit = true
- local isIgnorable = false
- if hit and hit.Transparency == 1 then
- isIgnorable = true
- end
- if hit and hit:IsDescendantOf(constructionsBin) then
- local structure = findStructureFromPart(hit)
- if structure and hit ~= structure.PrimaryPart then
- for _, part in next, structure:GetDescendants() do
- if part:IsA("BasePart") then
- newCollisionList[part] = true
- end
- end
- else
- newCollisionList[hit] = true
- end
- isIgnorable = true
- end
- if isIgnorable then
- table.insert(ignore, hit)
- hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
- goodHit = false
- end
- until goodHit
- local distance = (pos - castTo).magnitude
- if distance > shiftDistance then
- shiftDistance = distance
- end
- end
- camera.CFrame = cframe - ((cframe.p - focus.p).unit * shiftDistance)
- ----
- for part in next, lastTransparencyCollisions do
- if not newCollisionList[part] then
- if activeTweens[part] then
- activeTweens[part]:Cancel()
- end
- local props = {LocalTransparencyModifier = 0}
- local tween = tweenService:Create(part, COLLISION_TWEEN_INFO_OUT, props)
- tween.Completed:Connect(function()
- activeTweens[part] = nil
- tween:Destroy()
- end)
- activeTweens[part] = tween
- tween:Play()
- end
- end
- for part in next, newCollisionList do
- if activeTweens[part] then
- activeTweens[part]:Cancel()
- end
- local props = {LocalTransparencyModifier = COLLISION_TRANSPARENCY}
- local tween = tweenService:Create(part, COLLISION_TWEEN_INFO_IN, props)
- tween.Completed:Connect(function()
- activeTweens[part] = nil
- tween:Destroy()
- end)
- activeTweens[part] = tween
- tween:Play()
- end
- lastTransparencyCollisions = newCollisionList
- end
- ----
- userInput.InputChanged:Connect(function(input, skip)
- if not skip then
- if input.UserInputType == Enum.UserInputType.MouseMovement then
- rotateCamera(input)
- elseif input.UserInputType == Enum.UserInputType.MouseWheel then
- zoomCamera(input)
- end
- end
- end)
- userInput.InputBegan:Connect(function(input, skip)
- if not skip and input.KeyCode == Enum.KeyCode.F then
- intercom:Fire("Camera Shake", 10, 0.3)
- end
- end)
- intercom:Register("Camera Shake", function(intensity, duration)
- table.insert(cameraShakes, {
- Start = tick(),
- Length = duration,
- Intensity = intensity,
- })
- table.sort(cameraShakes, function(a, b)
- return a.Intensity > b.Intensity
- end)
- end)
- runService:BindToRenderStep("Camera Step", Enum.RenderPriority.Camera.Value, function()
- setCamera()
- collideCamera()
- end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement