I was following this tutorial Roblox FPS Tutorial Part 2 Shooting, Replication, Recoil - YouTube (11:00) and I’m on the recoil part but my recoil (unlike his) goes WAYYY too far back and the kick is like 10x larger than its supposed to be… Can someone help?
my code:
local plr = game.Players.LocalPlayer
local char = plr.CharacterAdded:Wait()
local humanoid = char:WaitForChild("Humanoid")
local HRP = char:FindFirstChild("HumanoidRootPart")
local camera = game.Workspace.CurrentCamera
local Aiming = false
local UIS = game:GetService("UserInputService")
local RS = game:GetService("RunService")
local GUIservice = game:GetService("GuiService")
local TS = game:GetService("TweenService")
local ReplicatedStorage =game:GetService("ReplicatedStorage")
--UIS.MouseIconEnabled = false DISABLE MOUSE CURSOR
local springModule = require(game.ReplicatedStorage.Spring)
local viewmodel = ReplicatedStorage.Viewmodel:Clone()
viewmodel.Parent = camera
local gunModel = viewmodel.AwesomeGun:Clone()
gunModel.Parent = viewmodel
local Joint = Instance.new("Motor6D")
Joint.Part0 = viewmodel.Primary
Joint.Part1 = gunModel.Handle
Joint.Parent = gunModel.Handle
Joint.C1 = CFrame.new(0,.2,.2)
local Anims = {
["Idle"] = viewmodel.AnimationController.Animator:LoadAnimation(ReplicatedStorage.Idle)
}
Anims.Idle:Play()
local AimingCF = CFrame.new()
local MouseSway = springModule.new(Vector3.new())
MouseSway.Speed = 20
MouseSway.Damper = .5
local MovementSway = springModule.new(Vector3.new())
MovementSway.Speed = 30
MovementSway.Damper = .4
local GunSpring = springModule.new(Vector3.new())
MouseSway.Speed = 20
MouseSway.Damper = .4
local RecoilSpring = springModule.new(Vector3.new())
MovementSway.Speed = 25
MovementSway.Damper = 1
local AUTO = true
local CD = 60/600
local CanShoot = true
local Shooting = false
local Range = 500
local KICK = Vector3.new(1,-1,1)
local RECOIL = Vector3.new(5,-0,10)
local RESETRECOIL = 0.2
local OOC = 2
local REC = 1
local RECOILS = {
{-1,1},
{-2,2},
{-3,3},
{-4,4},
{-10,10},
{-20,20}
}
local RECOILDAMPENER = 1
local Params = RaycastParams.new()
Params.FilterType = Enum.RaycastFilterType.Blacklist
Params.FilterDescendantsInstances = {viewmodel,char,workspace.FX}
local function getBobbing(Addition, Speed, Modifier)
return math.sin(time()*Addition*Speed)*Modifier
end
UIS.InputBegan:Connect(function(input,gpe)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
Aiming = true
elseif input.UserInputType == Enum.UserInputType.MouseButton1 then
Shooting = true
CanShoot = false
local StartShoot = time()
local Shots = 0
repeat
if Shots <#RECOILS then
Shots +=1
end
--GunSpring.Velocity += KICK
local Recoil = RECOIL
if time() - StartShoot > OOC then
RECOIL += Vector3.new(0,(math.sin(10*(time()-StartShoot))*25),0)
elseif time() - StartShoot > REC then
RECOIL += Vector3.new(0,(math.cos(5*(time()-StartShoot))*12),0)
end
local x = math.random(RECOILS[Shots][1]*10,RECOILS[Shots][2]*10)/10 - RECOILS[Shots][1]
local y = math.random(RECOILS[Shots][1]*10,RECOILS[Shots][2]*10)/10
local z = 0
Recoil += Vector3.new(x,y,z)
RECOIL/=RECOILDAMPENER
RecoilSpring.Velocity+=Recoil
print(RECOIL)
print(Recoil)
task.delay(RESETRECOIL, function()
RecoilSpring.Velocity-=Recoil
end)
task.wait(CD)
until Shooting == false or AUTO == false
end
end)
UIS.InputEnded:Connect(function(input,gpe)
if input.UserInputType == Enum.UserInputType.MouseButton2 then
Aiming = false
elseif input.UserInputType == Enum.UserInputType.MouseButton1 and Shooting then
Shooting = false
end
end)
RS:BindToRenderStep("Viewmodel",301, function(DT)
local mouseDelta = UIS:GetMouseDelta()
MouseSway.Velocity += (Vector3.new(mouseDelta.X /450,mouseDelta.Y/450))
local MovementSwayAmount = Vector3.new(getBobbing(10,1,.2),getBobbing(5,1,.2),getBobbing(5,1,.2))
if Aiming then
AimingCF = AimingCF:Lerp(gunModel.AimPart.CFrame:ToObjectSpace(viewmodel.PrimaryPart.CFrame),.3)
MovementSwayAmount/=6
humanoid.WalkSpeed = 7
else
AimingCF = AimingCF:Lerp(CFrame.new(), .3)
humanoid.WalkSpeed = 16
end
MovementSway.Velocity += ((MovementSwayAmount/25)* DT * 60 * HRP.AssemblyLinearVelocity.Magnitude)
camera.CFrame *= CFrame.Angles(math.rad(RecoilSpring.Position.X),math.rad(RecoilSpring.Position.Y),math.rad(RecoilSpring.Position.Z))
print(GunSpring.Position.Y)
viewmodel:PivotTo(
camera.CFrame * CFrame.new(MovementSway.Position.X/2,MovementSway.Position.Y/2,0)
*AimingCF
* CFrame.Angles(0,-MouseSway.Position.X,MouseSway.Position.Y)
* CFrame.Angles(0,MovementSway.Position.Y,MovementSway.Position.X)
* CFrame.Angles(GunSpring.Position.X,GunSpring.Position.Y,0)
* CFrame.new(0,0,GunSpring.Position.X * 5)
)
end)
plr.CharacterAdded:Connect(function(char)
char = plr.Character
humanoid = char:WaitForChild("Humanoid")
Params.FilterDescendantsInstances = {viewmodel,char,workspace.FX}
end)
Spring module:
--[[
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
Visualization (by Defaultio):
https://www.desmos.com/calculator/hn2i9shxbz
]]
local Spring = {}
--- Creates a new spring
-- @param initial A number or Vector3 (anything with * number and addition/subtraction defined)
-- @param[opt=os.clock] clock function to use to update spring
function Spring.new(initial, clock)
local target = initial or 0
clock = clock or os.clock
return setmetatable({
_clock = clock;
_time0 = clock();
_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 = self._clock()
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(self._clock())
return position
elseif index == "Velocity" or index == "v" then
local _, velocity = self:_positionVelocity(self._clock())
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
elseif index == "Clock" then
return self._clock
else
error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
end
end
function Spring:__newindex(index, value)
local now = self._clock()
if index == "Value" or index == "Position" or index == "p" then
local _, velocity = self:_positionVelocity(now)
self._position0 = value
self._velocity0 = velocity
self._time0 = now
elseif index == "Velocity" or index == "v" then
local position, _ = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = value
self._time0 = now
elseif index == "Target" or index == "t" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._target = value
self._time0 = now
elseif index == "Damper" or index == "d" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._damper = value
self._time0 = now
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
self._time0 = now
elseif index == "Clock" then
local position, velocity = self:_positionVelocity(now)
self._position0 = position
self._velocity0 = velocity
self._clock = value
self._time0 = value()
else
error(("%q is not a valid member of Spring"):format(tostring(index)), 2)
end
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