Two scripts changing cframe of camera at same time

I want to shake camera when specific events happen

The issue is im using first person script from iytgggggg and CameraShaker script from Stephen Leitnick that was ported from unity. Im making the camera shake from local script that handles loading screen but the first person script overrides any changes to the camera Cframe from the loading screen script because they use the same camera.

I think the way to do this is to integrate the shake into the FPS but the FPS is updating the camera constantly and i need to shake the camera only on some events and to start it from another scripts.

First Person Script placed in StarterPack

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 
								-- StarterGui -- 					
--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--
--	Place this into StarterGui or StarterPack							--
--	CREDIT																--
--	winter_beast768; for the initial script								--
--	SawyerDGamer; some stuff ripped from his panner script					--
--  iytgggggg; shoving it all into this script and then some :)			--
--	UPDATE: turned it into r15, made it so you can swim right in water	--
--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--	--


---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 


repeat wait() until game:GetService("Players").LocalPlayer.Character ~= nil
local runService = game:GetService("RunService")
local input = game:GetService("UserInputService")
local players = game:GetService("Players")

CanToggleMouse = {allowed = true; activationkey = Enum.KeyCode.F;} -- lets you move your mouse around in firstperson
CanViewBody = true 		-- whether you see your body
Sensitivity = 0.2		-- anything higher would make looking up and down harder; recommend anything between 0~1
Smoothness = 0.05		-- recommend anything between 0~1
FieldOfView = 90		-- fov

local cam = game.Workspace.CurrentCamera
local player = players.LocalPlayer
local m = player:GetMouse()
m.Icon = "http://www.roblox.com/asset/?id=569021388" -- replaces mouse icon
local character = player.Character or player.CharacterAdded:wait()
local humanoidpart = character.HumanoidRootPart

local head = character:WaitForChild("Head")
local CamPos,TargetCamPos = cam.CoordinateFrame.p,cam.CoordinateFrame.p 
local AngleX,TargetAngleX = 0,0
local AngleY,TargetAngleY = 0,0

local running = true
local freemouse = false

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 

function updatechar()
	
	for _, v in pairs(character:GetChildren())do
		if CanViewBody then
			if v.Name == 'Head' then
				v.LocalTransparencyModifier = 1
				v.CanCollide = false
			end
		else
			if v:IsA'Part' or v:IsA'UnionOperation' or v:IsA'MeshPart' then
				v.LocalTransparencyModifier = 1
				v.CanCollide = false
			end
		end
		if v:IsA'Accessory' then
			v:FindFirstChild('Handle').LocalTransparencyModifier = 1
			v:FindFirstChild('Handle').CanCollide = false
		end
		if v:IsA'Hat' then
			v:FindFirstChild('Handle').LocalTransparencyModifier = 1
			v:FindFirstChild('Handle').CanCollide = false
		end

	end
	
end

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 

input.InputChanged:connect(function(inputObject)
	
	if inputObject.UserInputType == Enum.UserInputType.MouseMovement then
		local delta = Vector2.new(inputObject.Delta.x/Sensitivity,inputObject.Delta.y/Sensitivity) * Smoothness

		local X = TargetAngleX - delta.y 
		TargetAngleX = (X >= 80 and 80) or (X <= -80 and -80) or X 
		TargetAngleY = (TargetAngleY - delta.x) %360 
	end	
	
end)

input.InputBegan:connect(function(inputObject)
	
	if inputObject.UserInputType == Enum.UserInputType.Keyboard then
		if inputObject.KeyCode == CanToggleMouse.activationkey then
			if CanToggleMouse.allowed and freemouse == false then
				freemouse = true
			else
				freemouse = false
			end
		end
	end
	
end)

---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ---- 

runService.RenderStepped:connect(function()
	 
	if running then
		updatechar()
		
		CamPos = CamPos + (TargetCamPos - CamPos) *0.28 
		AngleX = AngleX + (TargetAngleX - AngleX) *0.35 
		local dist = TargetAngleY - AngleY 
		dist = math.abs(dist) > 180 and dist - (dist / math.abs(dist)) * 360 or dist 
		AngleY = (AngleY + dist *0.35) %360
		cam.CameraType = Enum.CameraType.Scriptable
		
		cam.CoordinateFrame = CFrame.new(head.Position) 
		* CFrame.Angles(0,math.rad(AngleY),0) 
		* CFrame.Angles(math.rad(AngleX),0,0)
		* CFrame.new(0,0.8,0) -- offset
		
		humanoidpart.CFrame=CFrame.new(humanoidpart.Position)*CFrame.Angles(0,math.rad(AngleY),0)
		character.Humanoid.AutoRotate = false
		else game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default; character.Humanoid.AutoRotate = true
	end

	if (cam.Focus.p-cam.CoordinateFrame.p).magnitude < 1 then
		running = false
	else
		running = true
		if freemouse == true then
			game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.Default
		else
			game:GetService("UserInputService").MouseBehavior = Enum.MouseBehavior.LockCenter
		end
	end
	
	if not CanToggleMouse.allowed then
		freemouse = false
	end
	
	cam.FieldOfView = FieldOfView

end)


LoadingScript placed in ReplicatedFirst

local contentProvider = game:GetService("ContentProvider")
local SoundService = game:GetService("SoundService")
local ui = script:WaitForChild("Loading"):Clone()
local ui2 = script:WaitForChild("WarningGui"):Clone()
local ui3 = script:WaitForChild("Crazy")

repeat wait() until game:IsLoaded()

local MainSFX = SoundService["Gymnopedie No. 1"]
MainSFX:Play()

local assets = game:GetDescendants()
local MaxAssets = #assets

local Player =  game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local PlayerGui = Player:WaitForChild("PlayerGui")

ui.Parent = PlayerGui

for i, assetToLoad in assets do
	local size = i/MaxAssets
	local Percent = i/MaxAssets * 100
	local Bar = ui:WaitForChild("Background"):WaitForChild("LoadingBar"):WaitForChild("ProgressBar")
	contentProvider:PreloadAsync({assetToLoad})
	ui:WaitForChild("Background"):WaitForChild("Percentage").Text = math.ceil(Percent).."%"
	game.TweenService:Create(Bar, TweenInfo.new(0.1), {Size = UDim2.new(size, -1, 0.7, 0)}):Play()

end

wait(1)
ui2.Parent = PlayerGui
ui:Destroy()

local CameraShaker = require(game.ReplicatedStorage.CameraShaker)
local camShake = CameraShaker.new(Enum.RenderPriority.Camera.Value, function(shakeCFrame)
	camera.CFrame = camera.CFrame * shakeCFrame
end)

camShake:Start()

camShake:ShakeSustain(CameraShaker.Presets.Earthquake)

local function dream ()
	local SFX = SoundService["Creepy Ambience"]
	local musicPlayer = game.Workspace.GramophoneStart.Main["Nocturne in E-Flat Major, Op. 9, No. 2"]
	local Proximity = game.Workspace.GramophoneStart.ProximityPrompt
	
	SFX:Play()
	musicPlayer:Play()
	
	Proximity.Triggered:Connect(function()
		SoundService["FNAF SL - Tape Stop"]:Play()
		musicPlayer:Stop()
		wait(2)
		SoundService["Apartment Bumps 4 (SFX)"]:Play()
		wait(9.6)
		ui3.Parent = PlayerGui
		SoundService["Whispers (Loop)"]:Play()
		wait(1.5)
		SoundService["fnaf Tjoc: footstep sound effect"]:Play()
		wait(5)
		SoundService["fnaf Tjoc: footstep sound effect"]:Stop()
		wait(3)
		SoundService["FNAF AR - Freddy Jumpscare"]:Play()
		SoundService["Whispers (Loop)"]:Stop()
		ui3:Destroy()
	end)
	
	
end

local ButtonSFX = SoundService["Scary Sound"]
local Button = ui2.Background.ContinueButton

Button.MouseButton1Click:Connect(function()
	MainSFX:Stop()
	ButtonSFX:Play()
	wait(4)
	ui2:Destroy()
	dream()
	
end)


Im begginer in scripting so im really sorry for my code i know its probably the worst way to do what i want.

Thank you for any tips on how to do this.

You may want to have a BoolValue somewhere that both scripts can access, which represents whether or not the camera is shaking. That way you can prevent the first-person script from changing the CFrame while the camera is shaking.

If you switch both codes to use RunService:BindToRenderStep you can control which run in what order (e.g. the shake script should run after the FPS script).

e.g.

local RunService = game:GetService("RunService")

local function fpsScriptUpdate(delta)
	-- Take the code from the RunService.RenderStepped connection and put in in here
end

RunService:BindToRenderStep("Before camera", Enum.RenderPriority.Camera.Value + 1, beforeCamera)

Then for the second one use Enum.RenderPriority.Camera.Value + 2 so it runs after the FPS script, though I believe slietnick already uses BindToRenderStepped, so you’d just need to change the priority to something a little higher, if the change to the FPS script doesn’t fix it in the first place.

1 Like

Thank you it worked i switched the fps script to use renderstepped and just used higher value in the second script

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.