here is the scripts if you wanna check it out/take it
The gun works most of the time but occasionally ill have some frame glitches where the gun moves weirdly when shooting while aiming or sometimes the players camera will suddenly be stuck phasing through the gun? I’m using Quentys CFrame spring module with it so i dont really understand why this is happening.
heres what the phasing camera glitch looks like
Firing LocalScript
local CamPart = game.Workspace.M1Grand
local Firing = false
local CanFire = true
local Divide = 0.4
Zoomed = false
local CanShoot = true
Mouse.Button1Down:Connect(function()
Firing = true
end)
Mouse.Button1Up:Connect(function()
Firing = false
end)
Mouse.Button2Down:Connect(function()
CanFire = false
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart3.CFrame
script.Parent.Zoomed.Value = 1
for i=0, 0.8, 0.2 do
script.Parent.Offset.Value = script.Parent.Offset.Value + 0.3
game.Workspace.CurrentCamera.FieldOfView = game.Workspace.CurrentCamera.FieldOfView - 0.7
CamPart.CamPart2.CFrame = CamPart.CamPart2.CFrame:Lerp(CamPart.CamPart.CFrame, i)
wait()
end
CamPart.CamPart2.CFrame = CamPart.CamPart2.CFrame:Lerp(CamPart.CamPart.CFrame, 1)
script.Parent.Offset.Value = 1.5
CanFire = true
end)
Mouse.Button2Up:Connect(function()
CanFire = false
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart.CFrame
for i=0.2, 1, 0.2 do
script.Parent.Offset.Value = script.Parent.Offset.Value - 0.3
game.Workspace.CurrentCamera.FieldOfView = game.Workspace.CurrentCamera.FieldOfView + 0.7
CamPart.CamPart2.CFrame = CamPart.CamPart2.CFrame:Lerp(CamPart.CamPart3.CFrame, i)
wait()
end
script.Parent.Zoomed.Value = 0
script.Parent.Offset.Value = 0
CanFire = true
end)
while wait() do
if script.Parent.Zoomed.Value == 1 then
Zoomed = true
else
Zoomed = false
end
if CanFire then
if Firing then
if Zoomed then
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.new(0, -0.03, -0.02)
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.Angles(math.rad(-2), 0, 0)
game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.Angles(math.rad(1), 0, 0)
wait()
for i=0.1, 0, -0.2 do
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.new(0, 0.006, 0.004)
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.Angles(math.rad(0.4), 0, 0)
game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.Angles(math.rad(0.1), 0, 0)
wait()
end
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart.CFrame
game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.Angles(math.rad(0.1), 0, 0)
else
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.new(0, 0, -0.2)
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.Angles(math.rad(-6), 0, 0)
game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.Angles(math.rad(0.5), 0, 0)
wait()
for i=0.1, 0, -0.2 do
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.new(0, 0, 0.04)
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart2.CFrame * CFrame.Angles(math.rad(1.2), 0, 0)
game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.Angles(math.rad(0.05), 0, 0)
wait()
end
game.Workspace.M1Grand.CamPart2.CFrame = game.Workspace.M1Grand.CamPart3.CFrame
game.Workspace.CurrentCamera.CFrame = game.Workspace.CurrentCamera.CFrame * CFrame.Angles(math.rad(0.1), 0, 0)
end
end
end
end
Camera Movement localscript
local camera = workspace.CurrentCamera
local RunService = game:GetService("RunService")
local Spring = require(script:WaitForChild("Spring"))
local ZEROVECTOR =Vector3.new()
local viewmodelSpring = Spring.new(ZEROVECTOR)
viewmodelSpring.Speed = 16
viewmodelSpring.Damper = 0.99 --1 is perfect dampening
local Mouse = game.Players.LocalPlayer:GetMouse()
Zoomed = false
local function clampMagnitude(vector, maxMagnitude)
return (vector.Magnitude > maxMagnitude and (vector.Unit * maxMagnitude) or vector)
end
local deltaSensitivity = 2 -- increases force from mouse delta
--if negative force goes in opposite direction
local previousGoalCFrame = CFrame.new()
RunService.RenderStepped:Connect(function(step)
if script.Parent.Zoomed.Value == 1 then
Zoomed = true
else
Zoomed = false
end
if Zoomed then
local cameraOffset = CFrame.new(0, 0, -script.Parent.Offset.Value)
local goalCFrame = camera.CFrame*cameraOffset
part:SetPrimaryPartCFrame(goalCFrame)
--Spring stuff
local differenceCF = previousGoalCFrame:ToObjectSpace(goalCFrame)
local axis, angle = differenceCF:ToAxisAngle()
local angularDisplacement = axis*angle
previousGoalCFrame = goalCFrame
local springForce = angularDisplacement*deltaSensitivity
viewmodelSpring:Impulse(springForce)
local partSpringOffset = viewmodelSpring.Position
local axis = partSpringOffset.Unit
local angle = partSpringOffset.Magnitude
--clamp the angle don't want it to speen 360 degrees unless you want it to
--velocity goes wild though
--angle = math.deg(angle)
--local maxAngle = 45 --degrees
--angle = math.clamp(angle,0,45)
-- angle = math.rad(angle)
part:SetPrimaryPartCFrame(part.CamPart2.CFrame * CFrame.fromAxisAngle(axis,angle))
--part.CFrame *= CFrame.fromAxisAngle(axis,angle)
else
local cameraOffset = CFrame.new(0, 0, -script.Parent.Offset.Value)
local goalCFrame = camera.CFrame*cameraOffset
part:SetPrimaryPartCFrame(goalCFrame)
--Spring stuff
local differenceCF = previousGoalCFrame:ToObjectSpace(goalCFrame)
local axis, angle = differenceCF:ToAxisAngle()
local angularDisplacement = axis*angle
previousGoalCFrame = goalCFrame
local springForce = angularDisplacement*deltaSensitivity
viewmodelSpring:Impulse(springForce)
local partSpringOffset = viewmodelSpring.Position
local axis = partSpringOffset.Unit
local angle = partSpringOffset.Magnitude
--clamp the angle don't want it to speen 360 degrees unless you want it to
--velocity goes wild though
--angle = math.deg(angle)
--local maxAngle = 45 --degrees
--angle = math.clamp(angle,0,45)
-- angle = math.rad(angle)
part:SetPrimaryPartCFrame(part.CamPart2.CFrame * CFrame.fromAxisAngle(axis,angle))
--part.CFrame *= CFrame.fromAxisAngle(axis,angle)
end
end)
spring module by quenty scripts
class Spring
Description:
A physical model of a spring, useful in many applications. Properties only evaluate
upon index making this model good for lazy applications
API:
Spring = Spring.new(number position)
Creates a new spring in 1D
Spring = Spring.new(Vector3 position)
Creates a new spring in 3D
Spring.Position
Returns the current position
Spring.Velocity
Returns the current velocity
Spring.Target
Returns the target
Spring.Damper
Returns the damper
Spring.Speed
Returns the speed
Spring.Target = number/Vector3
Sets the target
Spring.Position = number/Vector3
Sets the position
Spring.Velocity = number/Vector3
Sets the velocity
Spring.Damper = number [0, 1]
Sets the spring damper, defaults to 1
Spring.Speed = number [0, infinity)
Sets the spring speed, defaults to 1
Spring:TimeSkip(number DeltaTime)
Instantly skips the spring forwards by that amount of now
Spring:Impulse(number/Vector3 velocity)
Impulses the spring, increasing velocity by the amount given
]]
local Spring = {}
--- Creates a new spring
-- @param initial A number or Vector3 (anything with * number and addition/subtraction defined)
function Spring.new(initial)
local target = initial or 0
return setmetatable({
_time0 = tick();
_position0 = target;
_velocity0 = 0*target;
_target = target;
_damper = 1;
_speed = 1;
}, Spring)
end
--- Impulse the spring with a change in velocity
-- @param velocity The velocity to impulse with
function Spring:Impulse(velocity)
self.Velocity = self.Velocity + velocity
end
--- Skip forwards in now
-- @param delta now to skip forwards
function Spring:TimeSkip(delta)
local now = tick()
local position, velocity = self:_positionVelocity(now+delta)
self._position0 = position
self._velocity0 = velocity
self._time0 = now
end
function Spring:__index(index)
if Spring[index] then
return Spring[index]
elseif index == "Value" or index == "Position" or index == "p" then
local position, _ = self:_positionVelocity(tick())
return position
elseif index == "Velocity" or index == "v" then
local _, velocity = self:_positionVelocity(tick())
return velocity
elseif index == "Target" or index == "t" then
return self._target
elseif index == "Damper" or index == "d" then
return self._damper
elseif index == "Speed" or index == "s" then
return self._speed
else
error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
end
end
function Spring:__newindex(index, value)
local now = tick()
if index == "Value" or index == "Position" or index == "p" then
local _, velocity = self:_positionVelocity(now)
self._position0 = value
self._velocity0 = velocity
elseif index == "Velocity" or index == "v" then
local position, _ = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = value
elseif index == "Target" or index == "t" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._target = value
elseif index == "Damper" or index == "d" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._damper = math.clamp(value, 0, 1)
elseif index == "Speed" or index == "s" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._speed = value < 0 and 0 or value
else
error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
end
self._time0 = now
end
function Spring:_positionVelocity(now)
local p0 = self._position0
local v0 = self._velocity0
local p1 = self._target
local d = self._damper
local s = self._speed
local t = s*(now - self._time0)
local d2 = d*d
local h, si, co
if d2 < 1 then
h = math.sqrt(1 - d2)
local ep = math.exp(-d*t)/h
co, si = ep*math.cos(h*t), ep*math.sin(h*t)
elseif d2 == 1 then
h = 1
local ep = math.exp(-d*t)/h
co, si = ep, ep*t
else
h = math.sqrt(d2 - 1)
local u = math.exp((-d + h)*t)/(2*h)
local v = math.exp((-d - h)*t)/(2*h)
co, si = u + v, u - v
end
local a0 = h*co + d*si
local a1 = 1 - (h*co + d*si)
local a2 = si/s
local b0 = -s*si
local b1 = s*si
local b2 = h*co - d*si
return
a0*p0 + a1*p1 + a2*v0,
b0*p0 + b1*p1 + b2*v0
end
return Spring
Heres a picture of explorer
(model is non cancollide and anchored)