Advertisement
Guest User

Untitled

a guest
Jun 24th, 2019
82
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 8.38 KB | None | 0 0
  1. local runService        = game:GetService("RunService")
  2. local players           = game:GetService("Players")
  3. local userInput         = game:GetService("UserInputService")
  4. local storage           = game:GetService("ReplicatedStorage")
  5. local tweenService      = game:GetService("TweenService")
  6.  
  7. local utilities         = storage:WaitForChild("Utilities")
  8. local intercom          = require(utilities:WaitForChild("Intercom"))
  9. local springs           = require(utilities:WaitForChild("Springs"))
  10.  
  11. local constructionsBin  = workspace:WaitForChild("Constructions")
  12.  
  13. ----
  14.  
  15. local lastTransparencyCollisions        = {}
  16. local activeTweens                      = {}
  17. local cameraShakes                      = {}
  18.  
  19. ----
  20.  
  21. local RNG = Random.new()
  22.  
  23. local HUMANOID_BASE_OFFSET  = Vector3.new(0, 1.5, 0)
  24. local HUMANOID_POST_OFFSET  = Vector3.new()
  25.  
  26. local TOOL_BASE_OFFSET      = Vector3.new(0, 2.5, 0)
  27. local TOOL_POST_OFFSET      = Vector3.new(0, 0, 2)
  28.  
  29. local CAMERA_POSITION       = Vector3.new()
  30. local CAMERA_SHAKE          = springs.new(Vector3.new(), 30, 0.7)
  31.  
  32. local CAMERA_ZOOM           = springs.new(10, 30, 1)
  33. local CAMERA_PRE_OFFSET     = springs.new(Vector3.new(), 30, 1)
  34. local CAMERA_POST_OFFSET    = springs.new(Vector3.new(), 30, 1)
  35.  
  36. local ZOOM_INCREMENT        = 1
  37. local ZOOM_MIN              = 3
  38. local ZOOM_MAX              = 12
  39.  
  40. local COLLISION_TRANSPARENCY        = 0.6
  41. local COLLISION_TWEEN_INFO_IN       = TweenInfo.new(0.05, Enum.EasingStyle.Quad, Enum.EasingDirection.In)
  42. local COLLISION_TWEEN_INFO_OUT      = TweenInfo.new(0.3, Enum.EasingStyle.Quad, Enum.EasingDirection.Out)
  43.  
  44. local CAMERA_ANGLES = {
  45.     Pitch   = 0,
  46.     Yaw     = 0,
  47.     Roll    = 0,
  48. }
  49.  
  50. local ANGLE_CLAMPS = {
  51.     Pitch   = {math.rad(-80), math.rad(75)},
  52.     Yaw     = {-math.huge, math.huge},
  53.     Roll    = {-math.huge, math.huge}  
  54. }
  55.  
  56. local CAST_SCREEN_SCALES = {
  57.     Vector2.new(0.5, 0.5),
  58.     Vector2.new(0, 0),
  59.     Vector2.new(1, 0),
  60.     Vector2.new(1, 1),
  61.     Vector2.new(0, 1),
  62. }
  63.  
  64. ----
  65.  
  66. local function clamp(val, min, max)
  67.     if val < min then
  68.         return min
  69.     elseif val > max then
  70.         return max
  71.     else
  72.         return val
  73.     end
  74. end
  75.    
  76. local function yawPitchRoll(x, y, z)
  77.     return CFrame.Angles(0, y, 0) * CFrame.Angles(x, 0, z)
  78. end
  79.  
  80. local function rollPitchYaw(x, y, z)
  81.     return CFrame.Angles(0, 0, z) * CFrame.Angles(x, y, 0)
  82. end
  83.  
  84. local function clampCamera()
  85.     for index, value in next, CAMERA_ANGLES do
  86.         CAMERA_ANGLES[index] = clamp(value, unpack(ANGLE_CLAMPS[index]))
  87.     end
  88. end
  89.  
  90. local function rotateCamera(input)
  91.     local change = input.Delta * math.rad(1) * 0.2
  92.    
  93.     CAMERA_ANGLES.Pitch = CAMERA_ANGLES.Pitch - change.Y
  94.     CAMERA_ANGLES.Yaw = CAMERA_ANGLES.Yaw - change.X
  95.    
  96.     clampCamera()
  97. end
  98.  
  99. local function zoomCamera(input)
  100.     local direction = math.sign(-input.Position.Z)
  101.     local current = CAMERA_ZOOM.Target
  102.    
  103.     local rawNew = current + (direction * ZOOM_INCREMENT)
  104.     local clamped = math.clamp(rawNew, ZOOM_MIN, ZOOM_MAX)
  105.    
  106.     CAMERA_ZOOM.Target = clamped   
  107. end
  108.  
  109. local function getShake()
  110.     for index = #cameraShakes, 1, -1 do
  111.         local data = cameraShakes[index]
  112.         local delta = tick() - data.Start
  113.        
  114.         if delta > data.Length then
  115.             table.remove(cameraShakes, index)
  116.         end
  117.     end
  118.    
  119.     return cameraShakes[1]
  120. end
  121.  
  122. local function setCamera()
  123.     local camera = workspace.CurrentCamera
  124.     local subject = camera.CameraSubject
  125.    
  126.     if camera.CameraType ~= Enum.CameraType.Custom then
  127.         return
  128.     end
  129.    
  130.     if subject and subject:IsA("Model") then
  131.         CAMERA_POST_OFFSET.Target = Vector3.new()
  132.         CAMERA_POSITION = subject:GetModelCFrame().p
  133.     elseif subject and subject:IsA("Humanoid") then
  134.         if subject.Parent:FindFirstChild("Tool") then
  135.             CAMERA_PRE_OFFSET.Target = TOOL_BASE_OFFSET
  136.             CAMERA_POST_OFFSET.Target = TOOL_POST_OFFSET
  137.         else
  138.             CAMERA_PRE_OFFSET.Target = HUMANOID_BASE_OFFSET
  139.             CAMERA_POST_OFFSET.Target = HUMANOID_POST_OFFSET
  140.         end
  141.        
  142.         CAMERA_POSITION = subject.Torso.CFrame * CAMERA_PRE_OFFSET:Solve()
  143.     end
  144.    
  145.     local rotatedOffset = CAMERA_POST_OFFSET:Solve() + Vector3.new(0, 0, CAMERA_ZOOM:Solve())
  146.    
  147.     local rotation = yawPitchRoll(CAMERA_ANGLES.Pitch, CAMERA_ANGLES.Yaw, CAMERA_ANGLES.Roll)  
  148.    
  149.     local position = CAMERA_POSITION + (rotation * rotatedOffset)
  150.    
  151.    
  152.     local shakeRotation = CFrame.new()
  153.     local workingShake = getShake()
  154.    
  155.     if workingShake then
  156.         local pitch = RNG:NextNumber(-0.5, 0.5) * workingShake.Intensity
  157.         local roll = RNG:NextNumber(-0.5, 0.5) * workingShake.Intensity
  158.        
  159.         CAMERA_SHAKE.Target = Vector3.new(pitch, 0, roll)
  160.        
  161.         local set = CAMERA_SHAKE:Solve() * math.rad(1)
  162.         local asCF = rollPitchYaw(set.X, set.Y, set.Z)
  163.        
  164.         shakeRotation = asCF
  165.     end
  166.  
  167.     camera.CFrame = (rotation * shakeRotation) + position
  168.     camera.Focus = CFrame.new(CAMERA_POSITION)
  169.    
  170.     userInput.MouseBehavior = Enum.MouseBehavior.LockCenter
  171. end
  172.  
  173. local function findStructureFromPart(object)
  174.     if object:IsDescendantOf(constructionsBin) then
  175.         if object.Parent == constructionsBin then
  176.             return object
  177.         else
  178.             return findStructureFromPart(object.Parent)
  179.         end
  180.     else
  181.         return nil
  182.     end
  183. end
  184.    
  185. local function collideCamera()
  186.     local ignore = {
  187.         workspace:WaitForChild("Characters"),
  188.         workspace:WaitForChild("Gem Bin"),
  189.         workspace:WaitForChild("ToolEffects")
  190.     }
  191.    
  192.     local newCollisionList = {}
  193.    
  194.     ----
  195.    
  196.     local camera = workspace.CurrentCamera
  197.     local cframe = camera.CFrame
  198.     local focus = camera.Focus
  199.     local viewSize = camera.ViewportSize
  200.     local clippingDist = 0.5
  201.    
  202.     local clippingOffset = cframe.lookVector * clippingDist
  203.     local baseDistance = (cframe.p - focus.p).magnitude
  204.     local shiftDistance = 0
  205.    
  206.     ----
  207.    
  208.     for _, screenVec in next, CAST_SCREEN_SCALES do
  209.         local screenPos = viewSize * screenVec
  210.         local castTo = camera:ViewportPointToRay(screenPos.X, screenPos.Y, clippingDist).Origin
  211.         local castFrom = focus.p + (castTo - (cframe.p + clippingOffset))
  212.  
  213.         local ray = Ray.new(castFrom, castTo - castFrom)
  214.         local hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
  215.        
  216.         repeat
  217.             local goodHit = true           
  218.             local isIgnorable = false
  219.            
  220.             if hit and hit.Transparency == 1 then
  221.                 isIgnorable = true
  222.             end
  223.            
  224.             if hit and hit:IsDescendantOf(constructionsBin) then
  225.                 local structure = findStructureFromPart(hit)
  226.                
  227.                 if structure and hit ~= structure.PrimaryPart then
  228.                     for _, part in next, structure:GetDescendants() do
  229.                         if part:IsA("BasePart") then
  230.                             newCollisionList[part] = true
  231.                         end
  232.                     end
  233.                 else
  234.                     newCollisionList[hit] = true
  235.                 end
  236.  
  237.                 isIgnorable = true
  238.             end        
  239.            
  240.             if isIgnorable then
  241.                 table.insert(ignore, hit)
  242.                 hit, pos = workspace:FindPartOnRayWithIgnoreList(ray, ignore)
  243.                 goodHit = false
  244.             end
  245.            
  246.         until goodHit      
  247.        
  248.         local distance = (pos - castTo).magnitude
  249.        
  250.         if distance > shiftDistance then
  251.             shiftDistance = distance
  252.         end    
  253.     end
  254.  
  255.     camera.CFrame = cframe - ((cframe.p - focus.p).unit * shiftDistance)
  256.    
  257.     ----
  258.    
  259.     for part in next, lastTransparencyCollisions do
  260.         if not newCollisionList[part] then
  261.             if activeTweens[part] then
  262.                 activeTweens[part]:Cancel()
  263.             end
  264.            
  265.             local props = {LocalTransparencyModifier = 0}
  266.             local tween = tweenService:Create(part, COLLISION_TWEEN_INFO_OUT, props)
  267.            
  268.             tween.Completed:Connect(function()
  269.                 activeTweens[part] = nil
  270.                 tween:Destroy()
  271.             end)
  272.            
  273.             activeTweens[part] = tween
  274.             tween:Play()           
  275.         end
  276.     end
  277.    
  278.     for part in next, newCollisionList do
  279.         if activeTweens[part] then
  280.             activeTweens[part]:Cancel()
  281.         end
  282.        
  283.         local props = {LocalTransparencyModifier = COLLISION_TRANSPARENCY}
  284.         local tween = tweenService:Create(part, COLLISION_TWEEN_INFO_IN, props)
  285.        
  286.         tween.Completed:Connect(function()
  287.             activeTweens[part] = nil
  288.             tween:Destroy()
  289.         end)
  290.        
  291.         activeTweens[part] = tween
  292.         tween:Play()   
  293.     end
  294.    
  295.     lastTransparencyCollisions = newCollisionList  
  296. end
  297.    
  298. ----
  299.  
  300. userInput.InputChanged:Connect(function(input, skip)
  301.     if not skip then
  302.         if input.UserInputType == Enum.UserInputType.MouseMovement then
  303.             rotateCamera(input)
  304.         elseif input.UserInputType == Enum.UserInputType.MouseWheel then
  305.             zoomCamera(input)
  306.         end
  307.     end
  308. end)
  309.  
  310. userInput.InputBegan:Connect(function(input, skip)
  311.     if not skip and input.KeyCode == Enum.KeyCode.F then
  312.         intercom:Fire("Camera Shake", 10, 0.3)
  313.     end
  314. end)
  315.  
  316. intercom:Register("Camera Shake", function(intensity, duration)
  317.     table.insert(cameraShakes, {
  318.         Start = tick(),
  319.         Length = duration,
  320.         Intensity = intensity,
  321.     })
  322.    
  323.     table.sort(cameraShakes, function(a, b)
  324.         return a.Intensity > b.Intensity
  325.     end)
  326. end)
  327.  
  328. runService:BindToRenderStep("Camera Step", Enum.RenderPriority.Camera.Value, function()
  329.     setCamera()
  330.     collideCamera()
  331. end)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement